This commit is contained in:
yulixing 2019-05-14 20:33:49 +08:00
parent b978b16e6a
commit 97ea1a48e5
13 changed files with 399 additions and 13 deletions

View File

@ -25,6 +25,7 @@
"fs-extra": "^8.0.0",
"glob": "^7.1.4",
"helmet": "^3.18.0",
"jsonwebtoken": "^8.5.1",
"ldapjs": "^1.0.2",
"method-override": "^3.0.0",
"mongoose": "^5.5.7",

View File

@ -172,11 +172,13 @@ app.use(function(err, req, res, next) {
if (req.path.startsWith('/api')) {
res.json({ errcode: 10, errmsg: err.message });
} else {
res.render('error', {
message: err.status === 404 ? err.message : '服务器君开小差啦 @(・●・)@',
error: err,
title: err.status
});
// TODO:
// res.render('error', {
// message: err.status === 404 ? err.message : '服务器君开小差啦 @(・●・)@',
// error: err,
// title: err.status
// });
}
});

View File

@ -1,11 +1,12 @@
import {Router} from 'express';
import { Router } from 'express';
import testCtrl from './test';
const router = new Router();
router.get('/test', async(req, res, next) => {
res.send({
msg: 'test!'
})
})
// TODO:
router.get('/test', testCtrl);
export default router;
export default router;

View File

@ -0,0 +1,37 @@
import { User, Role } from './../../models/admin/User';
export default function(req, res, next) {
// const newRole = new Role({
// rolename: 'normal',
// permissions: ['game-readable', 'sys-writable']
// });
// newRole.save(function(err, role) {
// console.log(role);
// });
// res.send({
// res: 'ok'
// })
// let normalid;
// Role.findOne({ rolename: 'normal' }).then(data => {
// normalid = data._id;
// console.log(normalid);
// User.updateOne(
// {
// username: 'yulixing'
// },
// {$pull: {permissions: null}}
// ).exec()
// });
User.findOne({username: "yulixing"}).populate({path: 'permissions'}).exec((err, res) => {
console.log(res)
console.log(res.permissions)
})
res.send({});
}

View File

@ -0,0 +1,11 @@
import { Router } from 'express';
import userListCtrl from './user-list';
const router = new Router();
router.get('/user-list', userListCtrl);
export default router;

View File

@ -0,0 +1,73 @@
import ldap from 'ldapjs';
import config from '../../../config/config';
import { User, LdapUser } from '../../models/admin/User';
export default function(req, res, next) {
const client = ldap.createClient({
url: config.ldap.url
});
const opts = {
filter: '(&(objectClass=posixAccount)(o=gmplatform))',
scope: 'sub',
timeLimit: 500
};
const data = [];
client.bind(config.ldap.user, config.ldap.pwd, function(err, bindRes) {
if (err) next(err);
client.search('ou=people,dc=kingsome,dc=cn', opts, function(
err,
searchRes
) {
if (err) next(err);
searchRes.on('searchEntry', function(entry) {
data.push(entry.object);
});
searchRes.on('error', function(err) {
client.unbind();
next(err);
});
searchRes.on('end', async function(result) {
try {
let users = data;
users = users.map(user => {
user.userinfo = user.uidNumber;
return user;
});
const delResult = await LdapUser.remove({});
const saveResult = await LdapUser.insertMany(data);
// 取出完整用户信息
// 首次查询
let compUserList = await LdapUser.find({}).populate({
path: 'userinfo'
});
compUserList.map(async user => {
if (!user.userinfo) {
const newUser = new User({
_id: user.uidNumber,
username: user.uid,
fullname: user.sn
});
await newUser.save();
}
});
// 再次查询
compUserList = await LdapUser.find({}).populate({
path: 'userinfo'
});
res.send({
res: compUserList
});
client.unbind();
} catch (err) {
next(err);
}
});
});
});
}

View File

@ -0,0 +1,12 @@
import { Router } from 'express';
import loginCtrl from './login';
import userInfoCtrl from './user-info';
const router = new Router();
router.post('/login', loginCtrl);
router.get('/user-info', userInfoCtrl);
export default router;

View File

@ -0,0 +1,90 @@
import ldap from 'ldapjs';
import jwt from 'jsonwebtoken';
import config from '../../../config/config';
import {User} from '../../models/admin/User';
export default function(req, res, next) {
const body = req.body;
const client = ldap.createClient({
url: config.ldap.url
});
const opts = {
filter: `(uid=${body.username})`,
scope: 'sub',
timeLimit: 500
};
const data = [];
client.bind(config.ldap.user, config.ldap.pwd, function(err, bindRes) {
if (err) next(err);
client.search('ou=people,dc=kingsome,dc=cn', opts, function(
err,
searchRes
) {
if (err) next(err);
searchRes.on('searchEntry', function(entry) {
data.push(entry.object);
});
searchRes.on('error', function(err) {
client.unbind();
next(err);
});
searchRes.on('end', function(result) {
if (data.length > 0) {
// 用户存在,验证密码
const user = data[0];
const dn = user.dn;
client.bind('cn=虞丽星,ou=people,dc=kingsome,dc=cn', 'yulixing123456', async function(err, verifyRes) {
// client.bind(dn, body.pwd, async function(err, verifyRes) {
// 登录成功
if (err === null) {
const token = jwt.sign(
{
username: user.uid
},
config.jwtSecret,
{
expiresIn: 60 * 60 * 2
}
);
try {
let userSearch = await User.findOne({ username: user.uid });
if (!userSearch) {
const newUser = new User({
_id:user.uidNumber,
username: user.uid,
fullname: user.sn,
});
const saveResult = await newUser.save();
console.log(saveResult)
userSearch = saveResult;
}
res.send({
errcode: 0,
token,
userInfo: userSearch
});
} catch (err) {
next(err);
}
} else {
console.log(err)
res.send({
errcode: 1,
errmsg: '密码不正确。'
});
}
});
} else {
// 用户不存在
res.send({
errcode: 2,
errmsg: '用户不存在。'
});
}
client.unbind();
});
});
});
}

View File

@ -0,0 +1,75 @@
import jwt from 'jsonwebtoken';
import config from '../../../config/config';
import { User } from '../../models/admin/User';
export default function(req, res, next) {
const BearerToken = req.headers.authorization;
console.log(BearerToken);
if (!BearerToken) {
// 无权限
res.send({
errcode: 1,
errmsg: '用户无权限。'
});
} else {
const token = getToken(BearerToken);
if (!token) {
// 异常
res.send({
errcode: 1,
errmsg: 'token 异常。'
});
} else {
jwt.verify(token, config.jwtSecret, async (err, decode) => {
if (err) {
// 验证不通过
res.send({
errcode: 1,
errmsg: err.message
});
} else {
// 验证通过
// 获取用户信息
try {
const username = decode.username;
const searchResult = await User.findOne({ username }).populate({
path: 'permissions'
}).exec();
console.log(searchResult);
if (!searchResult) {
res.send({
errcode: 1,
errmsg: '用户信息发生异常。'
});
} else {
let permissions = [...searchResult.permissions];
permissions = permissions.map(permission => {
return permission.permissions;
});
permissions = permissions.reduce((pre, cur) => {
return pre.concat([...cur]);
}, []);
const userInfo = JSON.parse(JSON.stringify(searchResult));
userInfo.permits = permissions;
res.send({
errcode: 0,
userInfo
});
}
} catch (err) {
next(err);
}
}
});
}
}
}
function getToken(str) {
const reg = /^Bearer (.+)/;
const result = reg.exec(str);
return result ? result[1] : '';
}

74
src/models/admin/User.js Normal file
View File

@ -0,0 +1,74 @@
'use strict';
import mongoose from 'mongoose';
/**
* 用户信息
*/
const UserSchema = new mongoose.Schema(
{
// uidNumber
_id: { type: String, required: true },
// 用户名
username: { type: String },
// 姓名
fullname: { type: String },
// 头像
avatar: {
type: String,
default:
'https://hbimg.huabanimg.com/dd46766769229284b75a0142d239c3f7a5f4a2bf37ead-9XoIGZ_fw658'
},
// 角色
roles: [{ type: String }],
// 权限组
permissions: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Role' }],
// 状态
status: { type: String, default: '0' },
// 签名
signature: { type: String },
// 备注
comment: { type: String },
// 更改人
lastModifiedBy: { type: String }
},
{
collection: 'users',
timestamps: true
}
);
/* 角色权限 */
const RoleSchema = new mongoose.Schema(
{
// 角色名
rolename: { type: String },
// 权限
permissions: [{ type: String }]
},
{
collection: 'roles',
timestamps: true
}
);
/* Ldap 用户 */
const LdapUserSchema = new mongoose.Schema(
{
cn: { type: String },
uid: { type: String },
uidNumber: { type: String },
userinfo: { type: String, ref: 'User' }
},
{
collection: 'ldap-users',
timestamps: true
}
);
const User = mongoose.model('User', UserSchema);
const Role = mongoose.model('Role', RoleSchema);
const LdapUser = mongoose.model('LdapUser', LdapUserSchema);
export { User, Role, LdapUser };

View File

@ -2,10 +2,14 @@
import {Router} from 'express';
import commonRouter from './../controllers/common'
import sysRouter from './../controllers/sys'
import usersRouter from './../controllers/users'
const router = new Router();
router.use('/common', commonRouter);
router.use('/sys', sysRouter);
router.use('/users', usersRouter);
export default router

View File

@ -50,7 +50,6 @@ app.get('/', function(req, res, next) {
//查询结束
res2.on('end', function(result) {
console.log('search status: ' + result);
console.log(entries)
if (entries.length !== 0) {
client.bind(entries[0].dn, 'yulixing123456', function(

7
test/test3.js Normal file
View File

@ -0,0 +1,7 @@
import {Role} from './../src/models/admin/User'
const newRole = new Role({
rolename: 'normal',
permissions: ['game-readable', 'sys-writable']
})