forked from Inspur/skyline
* support native openstack login.
This commit is contained in:
parent
94ac8e6764
commit
bf188151e8
|
@ -1,31 +1,94 @@
|
||||||
const SessionHelper = require('../lib/SessionHelper');
|
const SessionHelper = require('../lib/SessionHelper');
|
||||||
const urlApi = require('url');
|
|
||||||
const request = require('request');
|
const request = require('request');
|
||||||
const Consts = require('../constants');
|
const Consts = require('../constants');
|
||||||
const { getOEM } = require('../lib/util');
|
|
||||||
const logger = require('log4js').getLogger('INDEX');
|
|
||||||
const uuid = require('uuid');
|
const uuid = require('uuid');
|
||||||
exports.enabled = true;
|
exports.enabled = true;
|
||||||
exports.mapping = '/index.html';
|
exports.mapping = '/index.html';
|
||||||
|
|
||||||
exports.middlewares = function(router) {
|
async function getProjects(endpoint, unscopedToken) {
|
||||||
let __DEV__ = process.env.NODE_ENV === 'development';
|
let options = {
|
||||||
let serviceAddr = context.getResource('serviceAddr.json');
|
url: endpoint + '/v3/auth/projects',
|
||||||
return [
|
method: 'GET',
|
||||||
//获取OEM信息
|
json: true,
|
||||||
function(req, res, next) {
|
body: {},
|
||||||
getOEM(serviceAddr['keystone']).then(res => {
|
headers: {
|
||||||
let session = req.session;
|
'X-Auth-Token': unscopedToken
|
||||||
session = Object.assign(session, res);
|
}
|
||||||
next();
|
};
|
||||||
}).catch(e => {
|
return new Promise((resolve, reject) => {
|
||||||
next();
|
request(options, (error, response, body) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve(body);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getScopedToken(endpoint, unscopedToken, projectId) {
|
||||||
|
let options = {
|
||||||
|
url: endpoint + '/v3/auth/tokens',
|
||||||
|
method: 'POST',
|
||||||
|
json: true,
|
||||||
|
body: {
|
||||||
|
"auth": {
|
||||||
|
"identity": {
|
||||||
|
"methods": [
|
||||||
|
"token"
|
||||||
|
],
|
||||||
|
"token": {
|
||||||
|
"id": unscopedToken
|
||||||
|
}
|
||||||
},
|
},
|
||||||
//获取项目列表
|
"scope": {
|
||||||
function(req, res, next) {
|
"project": {
|
||||||
let session = req.session;
|
"id": projectId
|
||||||
let restUrl = "/v3/auth/projects";
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Auth-Token': unscopedToken
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
request(options, (error, response, body) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve({ response, body });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMenus() {
|
||||||
|
return { "m.systemmanage": true, "m.systemmanage.departmentmanage": true, "m.systemmanage.groupmanage": true, "m.systemmanage.ipsetting": true, "m.systemmanage.opreatelog": true, "m.systemmanage.paramsetting": true, "m.systemmanage.paramsetting.businesstemplate": true, "m.systemmanage.paramsetting.copyRightSetting": true, "m.systemmanage.paramsetting.logsetting": true, "m.systemmanage.paramsetting.metadata": true, "m.systemmanage.paramsetting.moduleswitch": true, "m.systemmanage.paramsetting.systemsetting": true, "m.systemmanage.projectmanage": true, "m.systemmanage.rolemanage": true, "m.systemmanage.serialnumber": true, "m.systemmanage.systemstatus": true, "m.systemmanage.usermanage": true, "m.network": true, "m.network.balance": true, "m.network.firewall": true, "m.network.flaotingip": true, "m.network.network": true, "m.network.router": true, "m.network.securitygroup": true, "m.network.topo": true, "m.network.vpn": true, "m.docker_server": true, "m.docker_server.clusters": true, "m.docker_server.images": true, "m.docker_server.instances": true, "m.docker_server.volume": true, "m.heat": true, "m.heat.stack": true, "m.heat.template": true, "m.calculate": true, "m.calculate.disk": true, "m.calculate.host": true, "m.calculate.instance": true, "m.calculate.keypair": true, "m.calculate.media": true, "m.calculate.resourcespec": true, "m.calculate.snapshot": true, "m.senlin": true, "m.workflow": true, "m.workflow.task": true, "m.operationmanage": true, "m.operationmanage.fault": true, "m.operationmanage.flowmanage": true, "m.operationmanage.orderapprove": true, "m.operationmanage.orderlist": true, "m.calculate.fileStorage": true, "m.calculate.physical": true, "m.database": true, "m.calculate.baremetal": true, "m.systemmanage.usermanage.add": true, "m.systemmanage.usermanage.assignrole": true, "m.systemmanage.usermanage.delete": true, "m.systemmanage.usermanage.disable": true, "m.systemmanage.usermanage.edit": true, "m.systemmanage.usermanage.enable": true, "m.systemmanage.usermanage.resetpassword": true, "m.systemmanage.usermanage.unlock": true, "m.systemmanage.usermanage.userroledetail": true, "m.systemmanage.rolemanage.add": true, "m.systemmanage.rolemanage.delete": true, "m.systemmanage.rolemanage.detail": true, "m.systemmanage.rolemanage.edit": true, "m.systemmanage.groupmanage.add": true, "m.systemmanage.groupmanage.assignrole": true, "m.systemmanage.groupmanage.delete": true, "m.systemmanage.groupmanage.edit": true, "m.systemmanage.groupmanage.personmanage": true, "m.systemmanage.ipsetting.add": true, "m.systemmanage.ipsetting.delete": true, "m.systemmanage.ipsetting.edit": true, "m.systemmanage.projectmanage.create": true, "m.systemmanage.projectmanage.delete": true, "m.systemmanage.projectmanage.edit": true, "m.systemmanage.projectmanage.roledetail": true, "m.systemmanage.projectmanage.updategroup": true, "m.systemmanage.projectmanage.updateperson": true, "m.systemmanage.projectmanage.updatequota": true, "m.systemmanage.projectmanage.usage": true, "m.startpage": true, "m.operationmanage.cost": true, "m.operationmanage.pricesetting": true, "m.operationmanage.report": true, "m.network.qos": true, "m.calculate.logictopo": true, "m.monitor": true, "m.monitor.AlertMange": true, "m.monitor.monitorset": true, "m.monitor.resourcemonitor": true, "m.systemmanage.paramsetting.pimsetting": true, "m.operationAnalysis": true, "m.operationAnalysis.TrendPredict": true, "m.monitor.CustomGraph": true, "m.operationAnalysis.HealthStatus": true, "m.operationAnalysis.logSearch": true, "m.operationAnalysis.logAnalysis": true, "m.operationAnalysis.logError": true, "m.docker_server.kbclusters": true, "m.calculate.recycleBin": true, "m.monitor.EventMonitor": true, "m.operationAnalysis.noThresholdAnomalyDetection": true, "m.systemmanage.certManage": true, "m.operationAnalysis.CLUSTER_RESOURCE_PREDICTION": true, "m.sahara": true, "m.sahara.cluster": true, "m.sahara.clustertemplate": true, "m.sahara.image": true, "m.sahara.nodegroup": true };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRegions() {
|
||||||
|
return [{ "region": "RegionOne", "region_id": "RegionOne", "active": true }];
|
||||||
|
}
|
||||||
|
|
||||||
|
function cutEndpointUrl(url) {
|
||||||
|
url = new URL(url);
|
||||||
|
let result = url.origin;
|
||||||
|
if (url.pathname !== '') {
|
||||||
|
result += '/'+url.pathname.split('/')[1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.middlewares = function (router) {
|
||||||
|
const __DEV__ = process.env.NODE_ENV === 'development';
|
||||||
|
const serviceAddr = context.getResource('serviceAddr.json');
|
||||||
|
const endpoint = `http://${serviceAddr.keystone}`;
|
||||||
|
return [
|
||||||
|
async function (req, res, next) {
|
||||||
|
const session = req.session;
|
||||||
|
|
||||||
session.poc = !!serviceAddr.poc;
|
session.poc = !!serviceAddr.poc;
|
||||||
session.objectStorageType = serviceAddr.objectStorageType || 'S3';
|
session.objectStorageType = serviceAddr.objectStorageType || 'S3';
|
||||||
session.S3SuperUser = serviceAddr.S3SuperUser || {};
|
session.S3SuperUser = serviceAddr.S3SuperUser || {};
|
||||||
|
@ -36,432 +99,54 @@ exports.middlewares = function(router) {
|
||||||
session.forceCheckCurrentUser = 'forceCheckCurrentUser' in serviceAddr ? serviceAddr.forceCheckCurrentUser : false;
|
session.forceCheckCurrentUser = 'forceCheckCurrentUser' in serviceAddr ? serviceAddr.forceCheckCurrentUser : false;
|
||||||
session.forceVNCPassword = 'forceVNCPassword' in serviceAddr ? serviceAddr.forceVNCPassword : false;
|
session.forceVNCPassword = 'forceVNCPassword' in serviceAddr ? serviceAddr.forceVNCPassword : false;
|
||||||
session.arch = serviceAddr.arch || 'x86';
|
session.arch = serviceAddr.arch || 'x86';
|
||||||
let host = serviceAddr['keystone'];
|
|
||||||
let url = urlApi.format({
|
const unscopedToken = session['token'];
|
||||||
protocol: Consts.HTTP,
|
// 获取项目
|
||||||
host: host
|
let projects = (await getProjects(endpoint, unscopedToken)).projects;
|
||||||
});
|
let projectId = '';
|
||||||
let options = {
|
if (projects.length > 0) {
|
||||||
url: url+restUrl,
|
projectId = projects[0].id;
|
||||||
//if you expect binary data, you should set encoding: null
|
projects[0].active = true;
|
||||||
// encoding : null, //让body 直接是buffer
|
|
||||||
method: Consts.GET,
|
|
||||||
json: true,
|
|
||||||
body: {},
|
|
||||||
qs: {},
|
|
||||||
headers: {
|
|
||||||
[Consts.KEY_CONTENT_TYPE]: Consts.CONTENT_TYPE,
|
|
||||||
[Consts.KEY_ACCEPT]: Consts.ACCEPT,
|
|
||||||
'X-Auth-Token': session[Consts.PROJECT_TOKEN]?session[Consts.PROJECT_TOKEN]:(session[Consts.KEY_TOKEN] || ""),
|
|
||||||
'language': session[Consts.KEY_LANGUAGE] || ""
|
|
||||||
}
|
}
|
||||||
};
|
// 通过项目获取pToken,并且获取roleId和roleType
|
||||||
request(options, function(error, response, body) {
|
let { body: tokenBody, response: tokenResponse } = await getScopedToken(endpoint, unscopedToken, projectId);
|
||||||
if (body && 'error' in body && String(body.error.code) === "401") {
|
let scopedToken = tokenResponse.headers['x-subject-token'];
|
||||||
let loginUrl = req.baseUrl ? (req.baseUrl + '/timeout.html') : '/timeout.html';
|
let roles = tokenBody.token.roles;
|
||||||
res.redirect(loginUrl+"?__="+new Date().getTime());
|
let catalog = tokenBody.token.catalog;
|
||||||
return;
|
let services = {};
|
||||||
|
for (let catalogItem of catalog) {
|
||||||
|
let endpointItem = catalogItem.endpoints[0];
|
||||||
|
services[catalogItem['name']] = cutEndpointUrl(endpointItem.url);
|
||||||
}
|
}
|
||||||
let projectList = [];
|
let region = 'RegionOne';
|
||||||
let projects = body.projects || [];
|
let roleType = '';
|
||||||
let flg = false;
|
let roleId = '';
|
||||||
let roleId = req.cookies.roleType;
|
let adminRole = roles.find(item => item.name === 'admin');
|
||||||
let projectName;
|
if (adminRole) {
|
||||||
let projectId = req.cookies.pid;
|
roleType = 0;
|
||||||
let roleType = req.cookies.roleType;
|
roleId = adminRole.id;
|
||||||
projects.forEach((item, key) => {
|
} else {
|
||||||
//用户cookie project id可用
|
let memberRole = roles.find(item => item.name === 'member');
|
||||||
//考虑切换环境情况
|
if (memberRole) {
|
||||||
if (item.project_id === projectId&&item.role_type === parseInt(roleType)) {
|
roleType = 2;
|
||||||
flg = true;
|
roleId = memberRole.id;
|
||||||
roleId = item.role_id;
|
|
||||||
projectName = item.project_name;
|
|
||||||
}
|
}
|
||||||
projectList.push({
|
|
||||||
name: item.project_name,
|
|
||||||
id: item.project_id,
|
|
||||||
roleId:item.role_id,
|
|
||||||
roleType:item.role_type,
|
|
||||||
uuid:item.project_id+"&"+item.role_type,
|
|
||||||
active: (item.project_id === projectId && item.role_type == roleType)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (!flg) {
|
|
||||||
projectId =(projectList[0] || {}).id;
|
|
||||||
roleType = (projectList[0] || {}).roleType;
|
|
||||||
projectName = (projectList[0] || {}).project_name;
|
|
||||||
roleId = (projectList[0] || {}).roleId;
|
|
||||||
(projectList[0] || {}).active = true;
|
|
||||||
}
|
}
|
||||||
let options = {
|
req.session[Consts.KEY_PROJECT_LIST] = projects;
|
||||||
// secure: !__DEV__,
|
req.session[Consts.PROJECT_TOKEN] = scopedToken;
|
||||||
maxAge: 1000 * 60 * 60 * 24, // would expire after 1 day
|
|
||||||
httpOnly: false, // The cookie only accessible by the web server
|
res.cookie('pid', projectId || "");
|
||||||
signed: false // Indicates if the cookie should be signed
|
res.cookie('roleType', roleType);
|
||||||
};
|
res.cookie('roleId', roleId);
|
||||||
// Set cookie
|
|
||||||
res.cookie('pid', projectId||"", options); // options is optional
|
|
||||||
res.cookie('roleType', roleType==undefined?"":roleType, options);
|
|
||||||
res.cookie('roleId', roleId==undefined?"":roleId, options);
|
|
||||||
req.body['pid'] = projectId;
|
|
||||||
req.body['roleType'] = roleType;
|
|
||||||
req.body['projectName'] = projectName;
|
|
||||||
req.session['pid'] = projectId;
|
req.session['pid'] = projectId;
|
||||||
req.session['roleId'] = roleId;
|
req.session['roleId'] = roleId;
|
||||||
req.session[Consts.KEY_ROLE_TYPE] = roleType;
|
|
||||||
req.session[Consts.KEY_PROJECT_LIST] = projectList;
|
|
||||||
req.session[Consts.KEY_ROLE_ID] = roleId;
|
|
||||||
req.session.save(function () {
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//获取菜单码
|
|
||||||
function(req, res, next) {
|
|
||||||
let session = req.session;
|
|
||||||
var body = req.body;
|
|
||||||
let restUrl = "/v3/inspur/auth/menus/"+(body.pid?(body.roleType==0?'-':body.pid):"null");
|
|
||||||
let serviceAddr = context.getResource('serviceAddr.json');
|
|
||||||
let host = serviceAddr['keystone'];
|
|
||||||
let url = urlApi.format({
|
|
||||||
protocol: Consts.HTTP,
|
|
||||||
host: host
|
|
||||||
});
|
|
||||||
let options = {
|
|
||||||
url: url+restUrl,
|
|
||||||
//if you expect binary data, you should set encoding: null
|
|
||||||
// encoding : null, //让body 直接是buffer
|
|
||||||
method: Consts.GET,
|
|
||||||
json: true,
|
|
||||||
body: {},
|
|
||||||
qs: {},
|
|
||||||
headers: {
|
|
||||||
[Consts.KEY_CONTENT_TYPE]: Consts.CONTENT_TYPE,
|
|
||||||
[Consts.KEY_ACCEPT]: Consts.ACCEPT,
|
|
||||||
'X-Auth-Token': session[Consts.PROJECT_TOKEN]?session[Consts.PROJECT_TOKEN]:(session[Consts.KEY_TOKEN] || ""),
|
|
||||||
'language': session[Consts.KEY_LANGUAGE] || ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request(options, function(error, response, body) {
|
|
||||||
if ( (body.error || {}).code + "" === "400") {
|
|
||||||
let loginUrl = req.baseUrl ? (req.baseUrl + '/timeout.html?serialnumber=no') : '/timeout.html?serialnumber=no';
|
|
||||||
res.redirect(loginUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( (body.error || {}).code + "" === "401") {
|
|
||||||
let loginUrl = req.baseUrl ? (req.baseUrl + '/timeout.html#') : '/timeout.html#';
|
|
||||||
res.redirect(loginUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let opeCodeList = {};
|
|
||||||
if (body.menus && body.menus.length>0) {
|
|
||||||
body.menus.forEach(function(item) {
|
|
||||||
let menuCode = item.menu_code;
|
|
||||||
opeCodeList[menuCode] = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
req.session[Consts.KEY_MENUCODE_LIST] = opeCodeList;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function (req, res, next) { // 如果用户没有任何项目,则无法通过获取ptoken获取endpoints,此时使用内置的leo账号获取leo的endpoint
|
|
||||||
let pid = req.body.pid;
|
|
||||||
if (pid) {
|
|
||||||
next();
|
|
||||||
} else {
|
|
||||||
let serviceAddr = context.getResource('serviceAddr.json');
|
|
||||||
let leoKeystonePassword = serviceAddr.leoKeystonePassword || '';
|
|
||||||
let host = urlApi.format({
|
|
||||||
protocol: Consts.HTTP,
|
|
||||||
host: serviceAddr['keystone']
|
|
||||||
});
|
|
||||||
let options = {
|
|
||||||
url: `${host}/v3/auth/tokens`,
|
|
||||||
method: Consts.POST,
|
|
||||||
json: true,
|
|
||||||
body: {
|
|
||||||
"auth": {
|
|
||||||
"identity": {
|
|
||||||
"methods": [
|
|
||||||
"password"
|
|
||||||
],
|
|
||||||
"password": {
|
|
||||||
"user": {
|
|
||||||
"name": "leo",
|
|
||||||
"domain": {
|
|
||||||
"name": "default"
|
|
||||||
},
|
|
||||||
"password": leoKeystonePassword
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
qs: {},
|
|
||||||
headers: {
|
|
||||||
[Consts.KEY_CONTENT_TYPE]: Consts.CONTENT_TYPE,
|
|
||||||
[Consts.KEY_ACCEPT]: Consts.ACCEPT
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request(options, function(error, response, body) {
|
|
||||||
req.session[Consts.KEY_SERVICES] = {};
|
|
||||||
req.session[Consts.KEY_REGION_SERVICES] = {};
|
|
||||||
req.session[Consts.KEY_REGIONS] = [];
|
|
||||||
if (error) {
|
|
||||||
next();
|
|
||||||
} else if (body.error) {
|
|
||||||
next();
|
|
||||||
} else {
|
|
||||||
let catalog = body.token.catalog;
|
|
||||||
let regionId = req.cookies.region_id;
|
|
||||||
let activeRegionId = '';
|
|
||||||
let regionServiceObj = {};
|
|
||||||
let regions = [];
|
|
||||||
let leoIndex = body.token.catalog.findIndex((item) => {
|
|
||||||
return item.name === 'leo';
|
|
||||||
});
|
|
||||||
catalog[leoIndex].endpoints.filter((endpoint) => {
|
|
||||||
return endpoint.interface === 'admin';
|
|
||||||
}).forEach(region => {
|
|
||||||
regions.push({
|
|
||||||
region: region.region,
|
|
||||||
region_id: region.region_id,
|
|
||||||
active: region.region_id === regionId
|
|
||||||
});
|
|
||||||
if (region.region_id === regionId) {
|
|
||||||
activeRegionId = regionId;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (activeRegionId === '') {
|
|
||||||
activeRegionId = regions[0].region_id;
|
|
||||||
regions[0].active = true;
|
|
||||||
}
|
|
||||||
body.token.catalog.forEach((service, index) => {
|
|
||||||
service.endpoints.forEach((endpoint, index1) => {
|
|
||||||
let urlRegExp = /^(https?:\/\/.*:\d*)\/?/;
|
|
||||||
if (endpoint.interface === 'admin') {
|
|
||||||
let matches = endpoint.url.match(urlRegExp);
|
|
||||||
if (matches) {
|
|
||||||
if (!regionServiceObj[endpoint.region_id]) {
|
|
||||||
regionServiceObj[endpoint.region_id] = {};
|
|
||||||
}
|
|
||||||
regionServiceObj[endpoint.region_id][service.name] = matches[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.session[Consts.KEY_SERVICES] = regionServiceObj[activeRegionId];
|
|
||||||
req.session[Consts.KEY_REGION_SERVICES] = regionServiceObj;
|
|
||||||
req.session[Consts.KEY_REGIONS] = regions;
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//获取ptoken
|
|
||||||
function(req, res, next) {
|
|
||||||
let session = req.session;
|
|
||||||
let domainList = session.domainList;
|
|
||||||
let projectList = session.projectList;
|
|
||||||
let body = req.body;
|
|
||||||
let restUrl = "/v3/auth/tokens";
|
|
||||||
let serviceAddr = context.getResource('serviceAddr.json');
|
|
||||||
let host = serviceAddr['keystone'];
|
|
||||||
let url = urlApi.format({
|
|
||||||
protocol: Consts.HTTP,
|
|
||||||
host: host
|
|
||||||
});
|
|
||||||
let getPIDTraceId = 'req-'+uuid.v1();
|
|
||||||
let options = {
|
|
||||||
url: url+restUrl,
|
|
||||||
//if you expect binary data, you should set encoding: null
|
|
||||||
// encoding : null, //让body 直接是buffer
|
|
||||||
method: Consts.POST,
|
|
||||||
json: true,
|
|
||||||
body: {},
|
|
||||||
qs: {},
|
|
||||||
headers: {
|
|
||||||
[Consts.KEY_CONTENT_TYPE]: Consts.CONTENT_TYPE,
|
|
||||||
[Consts.KEY_ACCEPT]: Consts.ACCEPT,
|
|
||||||
'X-Auth-Token': session[Consts.PROJECT_TOKEN]?session[Consts.PROJECT_TOKEN]:(session[Consts.KEY_TOKEN] || ""),
|
|
||||||
'language': session[Consts.KEY_LANGUAGE] || "",
|
|
||||||
'X-Openstack-Request-Id': getPIDTraceId
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let pid = body.pid;
|
|
||||||
let roleType = body.roleType;
|
|
||||||
let projectName = body.projectName;
|
|
||||||
let isLogin = false;
|
|
||||||
if (!pid) { // 无pid情况,只记录登录
|
|
||||||
next();
|
|
||||||
isLogin = true;
|
|
||||||
reordLog('', session['loginTraceId']);
|
|
||||||
} else {
|
|
||||||
let bodyParam = {
|
|
||||||
"auth": {
|
|
||||||
"identity": {
|
|
||||||
"methods": [
|
|
||||||
"token"
|
|
||||||
],
|
|
||||||
"token": {
|
|
||||||
"id": session[Consts.KEY_TOKEN]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scope": {
|
|
||||||
project: {
|
|
||||||
"id": pid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
options.body = bodyParam;
|
// 获取菜单
|
||||||
let traceId = getPIDTraceId;
|
req.session[Consts.KEY_MENUCODE_LIST] = await getMenus();
|
||||||
isLogin = !session[Consts.PROJECT_TOKEN];
|
req.session[Consts.KEY_SERVICES] = services;
|
||||||
if (isLogin) { // 如果是登陆,则使用登陆的追踪ID
|
req.session[Consts.KEY_REGION_SERVICES] = [];
|
||||||
traceId = session['loginTraceId'];
|
req.session[Consts.KEY_REGIONS] = await getRegions();
|
||||||
}
|
|
||||||
request(options, function(error, response, body) {
|
|
||||||
if ( (body.error || {}).code + "" === "401") {
|
|
||||||
let loginUrl = req.baseUrl ? (req.baseUrl + '/timeout.html#') : '/timeout.html#';
|
|
||||||
res.redirect(loginUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let pToken = response.headers["x-subject-token"];
|
|
||||||
let serviceObj = {};
|
|
||||||
let regionServiceObj = {};
|
|
||||||
let regionList = [];
|
|
||||||
let regionId = req.cookies.region_id;
|
|
||||||
let activeRegionId = "";
|
|
||||||
if (body.token&&body.token.catalog) {
|
|
||||||
//先查看有几个region,并记录下来
|
|
||||||
let keystoneIndex = body.token.catalog.findIndex((item) => {
|
|
||||||
return item.name === "keystone";
|
|
||||||
});
|
|
||||||
let regions = body.token.catalog[keystoneIndex].endpoints.filter((item) => {
|
|
||||||
return item.interface === "admin";
|
|
||||||
});
|
|
||||||
let flg = false;
|
|
||||||
regions.forEach((item, index) => {
|
|
||||||
regionList.push({
|
|
||||||
region: item.region,
|
|
||||||
region_id: item.region_id,
|
|
||||||
active: item.region_id === regionId
|
|
||||||
});
|
|
||||||
if (item.region_id === regionId) {
|
|
||||||
activeRegionId = item.region_id;
|
|
||||||
flg = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!flg) {
|
|
||||||
regionList[0].active = true;
|
|
||||||
activeRegionId = regionList[0].region_id;
|
|
||||||
}
|
|
||||||
let options = {
|
|
||||||
// secure: !__DEV__,
|
|
||||||
maxAge: 1000 * 60 * 60 * 24, // would expire after 1 day
|
|
||||||
httpOnly: false, // The cookie only accessible by the web server
|
|
||||||
signed: false // Indicates if the cookie should be signed
|
|
||||||
};
|
|
||||||
// Set cookie
|
|
||||||
res.cookie('region_id', activeRegionId, options); // options is optional
|
|
||||||
//过滤
|
|
||||||
body.token.catalog.forEach((service, index) => {
|
|
||||||
service.endpoints.forEach((endpoint, index1) => {
|
|
||||||
let urlRegExp = /^(https?:\/\/.*:\d*)\/?/;
|
|
||||||
if (endpoint.interface === 'admin') {
|
|
||||||
let matches = endpoint.url.match(urlRegExp);
|
|
||||||
if (matches) {
|
|
||||||
if (!regionServiceObj[endpoint.region_id]) {
|
|
||||||
regionServiceObj[endpoint.region_id] = {};
|
|
||||||
}
|
|
||||||
regionServiceObj[endpoint.region_id][service.name] = matches[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
req.session[Consts.PROJECT_TOKEN] = pToken;
|
|
||||||
req.session[Consts.KEY_SERVICES] = regionServiceObj[activeRegionId];
|
|
||||||
req.session[Consts.KEY_REGION_SERVICES] = regionServiceObj;
|
|
||||||
req.session[Consts.KEY_REGIONS] = regionList;
|
|
||||||
next();
|
next();
|
||||||
|
|
||||||
reordLog(activeRegionId, traceId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function reordLog(regionId, traceId) {
|
|
||||||
//记录登陆和切换项目日志
|
|
||||||
let o = {
|
|
||||||
url: url+"/v3/inspur/logs",
|
|
||||||
method: Consts.POST,
|
|
||||||
json: true,
|
|
||||||
body: {},
|
|
||||||
qs: {},
|
|
||||||
headers: {
|
|
||||||
[Consts.KEY_CONTENT_TYPE]: Consts.CONTENT_TYPE,
|
|
||||||
[Consts.KEY_ACCEPT]: Consts.ACCEPT,
|
|
||||||
'language': session[Consts.KEY_LANGUAGE] || "",
|
|
||||||
'X-Auth-Token':session[Consts.PROJECT_TOKEN]?session[Consts.PROJECT_TOKEN]:(session[Consts.KEY_TOKEN] || "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let date = new Date();
|
|
||||||
let time = date.getTime()+date.getTimezoneOffset()*60*1000;
|
|
||||||
o.body = {
|
|
||||||
logs:[{
|
|
||||||
user_name: session[Consts.KEY_USER_NAME],
|
|
||||||
user_id:session[Consts.KEY_USER_ID],
|
|
||||||
region_id:regionId||"",
|
|
||||||
project_id:pid?(roleType==0?"":pid):"",
|
|
||||||
target:"user",
|
|
||||||
log_level:"info",
|
|
||||||
ip:session[Consts.KEY_IP],
|
|
||||||
create_time:time,
|
|
||||||
description:"user:"+session[Consts.KEY_USER_NAME]+" login",
|
|
||||||
language:"en",
|
|
||||||
trace_id: traceId
|
|
||||||
}, {
|
|
||||||
user_name: session[Consts.KEY_USER_NAME],
|
|
||||||
user_id:session[Consts.KEY_USER_ID],
|
|
||||||
region_id:regionId||"",
|
|
||||||
project_id:pid?(roleType==0?"":pid):"",
|
|
||||||
target:"用户",
|
|
||||||
log_level:"信息",
|
|
||||||
ip:session[Consts.KEY_IP],
|
|
||||||
create_time:time,
|
|
||||||
description:"用户:"+session[Consts.KEY_USER_NAME]+"登录",
|
|
||||||
language:"zh_cn",
|
|
||||||
trace_id: traceId
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
if (!isLogin) { //代表切换项目
|
|
||||||
if (req.cookies.switch!="region") {
|
|
||||||
if (roleType==0) {
|
|
||||||
o.body.logs[0].description = "user:"+session[Consts.KEY_USER_NAME]+" enter all";
|
|
||||||
o.body.logs[1].description = "用户:"+session[Consts.KEY_USER_NAME]+" 进入所有";
|
|
||||||
} else {
|
|
||||||
o.body.logs[0].description = "user:"+session[Consts.KEY_USER_NAME]+" enter project:"+(projectName||"");
|
|
||||||
o.body.logs[1].description = "用户:"+session[Consts.KEY_USER_NAME]+" 进入项目:"+(projectName||"");
|
|
||||||
}
|
|
||||||
} else if (req.cookies.switch=="region"){
|
|
||||||
let region = req.cookies.region_id;
|
|
||||||
o.body.logs[0].description = "user:"+session[Consts.KEY_USER_NAME]+" enter region:"+(region||"");
|
|
||||||
o.body.logs[1].description = "用户:"+session[Consts.KEY_USER_NAME]+" 进入region:"+(region||"");
|
|
||||||
}
|
|
||||||
res.cookie('switch', "", {
|
|
||||||
// secure: !__DEV__,
|
|
||||||
maxAge: 1000 * 60 * 60 * 24,
|
|
||||||
httpOnly: false,
|
|
||||||
signed: false
|
|
||||||
});
|
|
||||||
request(o, function () {})
|
|
||||||
} else { //如果没有ptoken,代表刚登陆进来
|
|
||||||
o.body.logs[0].description = "user:"+session[Consts.KEY_USER_NAME]+" login";
|
|
||||||
o.body.logs[1].description = "用户:"+session[Consts.KEY_USER_NAME]+"登录";
|
|
||||||
request(o, function () {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,33 +62,7 @@ module.exports = function (options, context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setIPContinuousWrongNumber(ip, success) {
|
async function setIPContinuousWrongNumber(ip, success) {
|
||||||
try {
|
|
||||||
const connection = await mysql.createConnection({
|
|
||||||
host: serviceAddr.mysql.host,
|
|
||||||
port: serviceAddr.mysql.port,
|
|
||||||
user: serviceAddr.mysql.user,
|
|
||||||
password: serviceAddr.mysql.password,
|
|
||||||
database: serviceAddr.mysql.database
|
|
||||||
});
|
|
||||||
let existingResults = await connection.query(`SELECT * FROM login_ip_logs WHERE ip = ?`, [ip]);
|
|
||||||
if (existingResults.length > 0) {
|
|
||||||
if (success) {
|
|
||||||
await connection.query(`UPDATE login_ip_logs SET continuous_wrong_numbers = ? WHERE id = ?`, [0, existingResults[0].id]);
|
|
||||||
} else {
|
|
||||||
await connection.query(`UPDATE login_ip_logs SET continuous_wrong_numbers = continuous_wrong_numbers + 1 WHERE id = ?`, [existingResults[0].id]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (success) {
|
|
||||||
await connection.query(`INSERT INTO login_ip_logs (ip, continuous_wrong_numbers, update_time) VALUES (?, ?, ?)`, [ip, 0, new Date()]);
|
|
||||||
} else {
|
|
||||||
await connection.query(`INSERT INTO login_ip_logs (ip, continuous_wrong_numbers, update_time) VALUES (?, ?, ?)`, [ip, 1, new Date()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await connection.end();
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSessionCount(req) {
|
function getSessionCount(req) {
|
||||||
|
|
|
@ -65,7 +65,6 @@ ElementUI.Select.props.placeholder.default = Vue.t('base.pleaseSelect');
|
||||||
ElementUI.Cascader.props.placeholder.default = Vue.t('base.pleaseSelect');
|
ElementUI.Cascader.props.placeholder.default = Vue.t('base.pleaseSelect');
|
||||||
|
|
||||||
//绑定logTarget
|
//绑定logTarget
|
||||||
console.log(logTarget);
|
|
||||||
Vue.logTarget = logTarget;
|
Vue.logTarget = logTarget;
|
||||||
|
|
||||||
// 4. 创建和挂载根实例。
|
// 4. 创建和挂载根实例。
|
||||||
|
|
|
@ -2,10 +2,10 @@ import rules from "./rules";
|
||||||
const Schema = require('async-validator');
|
const Schema = require('async-validator');
|
||||||
export default {
|
export default {
|
||||||
init() {
|
init() {
|
||||||
rules.forEach((item, index) => {
|
for (let item of rules) {
|
||||||
Schema.messages[item.type] = Vue.t(item.message);
|
Schema.messages[item.type] = Vue.t(item.message);
|
||||||
Schema.register(item.type, item.validator);
|
Schema.register(item.type, item.validator);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue