正在显示
21 个修改的文件
包含
580 行增加
和
0 行删除
.autod.conf.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +module.exports = { | ||
4 | + write: true, | ||
5 | + prefix: '^', | ||
6 | + plugin: 'autod-egg', | ||
7 | + test: [ | ||
8 | + 'test', | ||
9 | + 'benchmark', | ||
10 | + ], | ||
11 | + devdep: [ | ||
12 | + 'egg', | ||
13 | + 'egg-ci', | ||
14 | + 'egg-bin', | ||
15 | + 'autod', | ||
16 | + 'autod-egg', | ||
17 | + 'eslint', | ||
18 | + 'eslint-config-egg', | ||
19 | + ], | ||
20 | + exclude: [ | ||
21 | + './test/fixtures', | ||
22 | + './docs', | ||
23 | + './coverage', | ||
24 | + ], | ||
25 | +}; |
.eslintignore
0 → 100644
1 | +coverage |
.github/PULL_REQUEST_TEMPLATE.md
0 → 100644
1 | +<!-- | ||
2 | +Thank you for your pull request. Please review below requirements. | ||
3 | +Bug fixes and new features should include tests and possibly benchmarks. | ||
4 | +Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md | ||
5 | + | ||
6 | +感谢您贡献代码。请确认下列 checklist 的完成情况。 | ||
7 | +Bug 修复和新功能必须包含测试,必要时请附上性能测试。 | ||
8 | +Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md | ||
9 | +--> | ||
10 | + | ||
11 | +##### Checklist | ||
12 | +<!-- Remove items that do not apply. For completed items, change [ ] to [x]. --> | ||
13 | + | ||
14 | +- [ ] `npm test` passes | ||
15 | +- [ ] tests and/or benchmarks are included | ||
16 | +- [ ] documentation is changed or added | ||
17 | +- [ ] commit message follows commit guidelines | ||
18 | + | ||
19 | +##### Affected core subsystem(s) | ||
20 | +<!-- Provide affected core subsystem(s). --> | ||
21 | + | ||
22 | + | ||
23 | +##### Description of change | ||
24 | +<!-- Provide a description of the change below this comment. --> |
.github/workflows/nodejs.yml
0 → 100644
1 | +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node | ||
2 | +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions | ||
3 | + | ||
4 | +name: Node.js CI | ||
5 | + | ||
6 | +on: | ||
7 | + push: | ||
8 | + branches: | ||
9 | + - main | ||
10 | + - master | ||
11 | + pull_request: | ||
12 | + branches: | ||
13 | + - main | ||
14 | + - master | ||
15 | + schedule: | ||
16 | + - cron: '0 2 * * *' | ||
17 | + | ||
18 | +jobs: | ||
19 | + build: | ||
20 | + runs-on: ${{ matrix.os }} | ||
21 | + | ||
22 | + strategy: | ||
23 | + fail-fast: false | ||
24 | + matrix: | ||
25 | + node-version: [8, 10] | ||
26 | + os: [ubuntu-latest, windows-latest, macos-latest] | ||
27 | + | ||
28 | + steps: | ||
29 | + - name: Checkout Git Source | ||
30 | + uses: actions/checkout@v2 | ||
31 | + | ||
32 | + - name: Use Node.js ${{ matrix.node-version }} | ||
33 | + uses: actions/setup-node@v1 | ||
34 | + with: | ||
35 | + node-version: ${{ matrix.node-version }} | ||
36 | + | ||
37 | + - name: Install Dependencies | ||
38 | + run: npm i -g npminstall && npminstall | ||
39 | + | ||
40 | + - name: Continuous Integration | ||
41 | + run: npm run ci | ||
42 | + | ||
43 | + - name: Code Coverage | ||
44 | + uses: codecov/codecov-action@v1 | ||
45 | + with: | ||
46 | + token: ${{ secrets.CODECOV_TOKEN }} |
.gitignore
0 → 100644
.travis.yml
0 → 100644
LICENSE
0 → 100644
1 | +The MIT License (MIT) | ||
2 | + | ||
3 | +Copyright (c) 2019-present Alibaba Group Holding Limited and other contributors. | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | +of this software and associated documentation files (the "Software"), to deal | ||
7 | +in the Software without restriction, including without limitation the rights | ||
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | +copies of the Software, and to permit persons to whom the Software is | ||
10 | +furnished to do so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | +SOFTWARE. |
README.md
0 → 100644
1 | +# egg-ldapjs | ||
2 | + | ||
3 | +[![NPM version][npm-image]][npm-url] | ||
4 | +[![build status][travis-image]][travis-url] | ||
5 | +[![Test coverage][codecov-image]][codecov-url] | ||
6 | +[![David deps][david-image]][david-url] | ||
7 | +[![Known Vulnerabilities][snyk-image]][snyk-url] | ||
8 | +[![npm download][download-image]][download-url] | ||
9 | + | ||
10 | +[npm-image]: https://img.shields.io/npm/v/egg-ldapjs.svg?style=flat-square | ||
11 | +[npm-url]: https://npmjs.org/package/egg-ldapjs | ||
12 | +[travis-image]: https://img.shields.io/travis/eggjs/egg-ldapjs.svg?style=flat-square | ||
13 | +[travis-url]: https://travis-ci.org/eggjs/egg-ldapjs | ||
14 | +[codecov-image]: https://img.shields.io/codecov/c/github/eggjs/egg-ldapjs.svg?style=flat-square | ||
15 | +[codecov-url]: https://codecov.io/github/eggjs/egg-ldapjs?branch=master | ||
16 | +[david-image]: https://img.shields.io/david/eggjs/egg-ldapjs.svg?style=flat-square | ||
17 | +[david-url]: https://david-dm.org/eggjs/egg-ldapjs | ||
18 | +[snyk-image]: https://snyk.io/test/npm/egg-ldapjs/badge.svg?style=flat-square | ||
19 | +[snyk-url]: https://snyk.io/test/npm/egg-ldapjs | ||
20 | +[download-image]: https://img.shields.io/npm/dm/egg-ldapjs.svg?style=flat-square | ||
21 | +[download-url]: https://npmjs.org/package/egg-ldapjs | ||
22 | + | ||
23 | +<!-- | ||
24 | +Description here. | ||
25 | +--> | ||
26 | + | ||
27 | +## Install | ||
28 | + | ||
29 | +```bash | ||
30 | +$ npm i egg-ldapjs --save | ||
31 | +``` | ||
32 | + | ||
33 | +## Usage | ||
34 | + | ||
35 | +```js | ||
36 | +// {app_root}/config/plugin.js | ||
37 | +exports.ldapjs = { | ||
38 | + enable: true, | ||
39 | + package: 'egg-ldapjs', | ||
40 | +}; | ||
41 | +``` | ||
42 | + | ||
43 | +## Configuration | ||
44 | + | ||
45 | +```js | ||
46 | +// {app_root}/config/config.default.js | ||
47 | +exports.ldapjs = { | ||
48 | +}; | ||
49 | +``` | ||
50 | + | ||
51 | +see [config/config.default.js](config/config.default.js) for more detail. | ||
52 | + | ||
53 | +## Example | ||
54 | + | ||
55 | +<!-- example here --> | ||
56 | + | ||
57 | +## Questions & Suggestions | ||
58 | + | ||
59 | +Please open an issue [here](https://github.com/eggjs/egg/issues). | ||
60 | + | ||
61 | +## License | ||
62 | + | ||
63 | +[MIT](LICENSE) |
README.zh_CN.md
0 → 100644
1 | +# egg-ldapjs | ||
2 | + | ||
3 | +[![NPM version][npm-image]][npm-url] | ||
4 | +[![build status][travis-image]][travis-url] | ||
5 | +[![Test coverage][codecov-image]][codecov-url] | ||
6 | +[![David deps][david-image]][david-url] | ||
7 | +[![Known Vulnerabilities][snyk-image]][snyk-url] | ||
8 | +[![npm download][download-image]][download-url] | ||
9 | + | ||
10 | +[npm-image]: https://img.shields.io/npm/v/egg-ldapjs.svg?style=flat-square | ||
11 | +[npm-url]: https://npmjs.org/package/egg-ldapjs | ||
12 | +[travis-image]: https://img.shields.io/travis/eggjs/egg-ldapjs.svg?style=flat-square | ||
13 | +[travis-url]: https://travis-ci.org/eggjs/egg-ldapjs | ||
14 | +[codecov-image]: https://img.shields.io/codecov/c/github/eggjs/egg-ldapjs.svg?style=flat-square | ||
15 | +[codecov-url]: https://codecov.io/github/eggjs/egg-ldapjs?branch=master | ||
16 | +[david-image]: https://img.shields.io/david/eggjs/egg-ldapjs.svg?style=flat-square | ||
17 | +[david-url]: https://david-dm.org/eggjs/egg-ldapjs | ||
18 | +[snyk-image]: https://snyk.io/test/npm/egg-ldapjs/badge.svg?style=flat-square | ||
19 | +[snyk-url]: https://snyk.io/test/npm/egg-ldapjs | ||
20 | +[download-image]: https://img.shields.io/npm/dm/egg-ldapjs.svg?style=flat-square | ||
21 | +[download-url]: https://npmjs.org/package/egg-ldapjs | ||
22 | + | ||
23 | +<!-- | ||
24 | +Description here. | ||
25 | +--> | ||
26 | + | ||
27 | +## 依赖说明 | ||
28 | + | ||
29 | +### 依赖的 egg 版本 | ||
30 | + | ||
31 | +egg-ldapjs 版本 | egg 1.x | ||
32 | +--- | --- | ||
33 | +1.x | 😁 | ||
34 | +0.x | ❌ | ||
35 | + | ||
36 | +### 依赖的插件 | ||
37 | +<!-- | ||
38 | + | ||
39 | +如果有依赖其它插件,请在这里特别说明。如 | ||
40 | + | ||
41 | +- security | ||
42 | +- multipart | ||
43 | + | ||
44 | +--> | ||
45 | + | ||
46 | +## 开启插件 | ||
47 | + | ||
48 | +```js | ||
49 | +// config/plugin.js | ||
50 | +exports.ldapjs = { | ||
51 | + enable: true, | ||
52 | + package: 'egg-ldapjs', | ||
53 | +}; | ||
54 | +``` | ||
55 | + | ||
56 | +## 使用场景 | ||
57 | + | ||
58 | +- Why and What: 描述为什么会有这个插件,它主要在完成一件什么事情。 | ||
59 | +尽可能描述详细。 | ||
60 | +- How: 描述这个插件是怎样使用的,具体的示例代码,甚至提供一个完整的示例,并给出链接。 | ||
61 | + | ||
62 | +## 详细配置 | ||
63 | + | ||
64 | +请到 [config/config.default.js](config/config.default.js) 查看详细配置项说明。 | ||
65 | + | ||
66 | +## 单元测试 | ||
67 | + | ||
68 | +<!-- 描述如何在单元测试中使用此插件,例如 schedule 如何触发。无则省略。--> | ||
69 | + | ||
70 | +## 提问交流 | ||
71 | + | ||
72 | +请到 [egg issues](https://github.com/eggjs/egg/issues) 异步交流。 | ||
73 | + | ||
74 | +## License | ||
75 | + | ||
76 | +[MIT](LICENSE) |
app.js
0 → 100644
appveyor.yml
0 → 100644
1 | +environment: | ||
2 | + matrix: | ||
3 | + - nodejs_version: '8' | ||
4 | + - nodejs_version: '10' | ||
5 | + | ||
6 | +install: | ||
7 | + - ps: Install-Product node $env:nodejs_version | ||
8 | + - npm i npminstall && node_modules\.bin\npminstall | ||
9 | + | ||
10 | +test_script: | ||
11 | + - node --version | ||
12 | + - npm --version | ||
13 | + - npm run test | ||
14 | + | ||
15 | +build: off |
config/config.default.js
0 → 100644
lib/ldap.js
0 → 100644
1 | +'use strict'; | ||
2 | +const assert = require('assert'); | ||
3 | +const Promise = require('any-promise'); | ||
4 | +const ldap = require('ldapjs'); | ||
5 | + | ||
6 | +let count = 0; | ||
7 | + | ||
8 | +module.exports = app => { | ||
9 | + app.addSingleton('ldapjs', createClient); | ||
10 | +}; | ||
11 | + | ||
12 | +function createClient(config, app) { | ||
13 | + assert(config.url && config.dn && config.password, | ||
14 | + `[egg-ldapjs] 'url: ${config.url}', 'dn: ${config.dn}', 'password: ${config.password}' are required on config`); | ||
15 | + | ||
16 | + app.coreLogger.info('[egg-ldapjs] connecting %s@%s:%s/%s', | ||
17 | + config.dn, config.url); | ||
18 | + | ||
19 | + const LdapClient = options => { | ||
20 | + this.client = ldap.createClient(options); | ||
21 | + }; | ||
22 | + function promisify(fn) { | ||
23 | + return function() { | ||
24 | + const client = this.client; | ||
25 | + const args = Array.prototype.slice.call(arguments); | ||
26 | + | ||
27 | + return new Promise(function(resolve, reject) { | ||
28 | + args.push(function(err, result) { | ||
29 | + if (err) reject(err); | ||
30 | + else resolve(result); | ||
31 | + }); | ||
32 | + | ||
33 | + client[fn].apply(client, args); | ||
34 | + }); | ||
35 | + }; | ||
36 | + } | ||
37 | + | ||
38 | + [ 'bind', 'add', 'compare', 'del', 'exop', 'modify', 'modifyDN', 'unbind' ].forEach(function(fn) { | ||
39 | + LdapClient.prototype[fn] = promisify(fn); | ||
40 | + }); | ||
41 | + | ||
42 | + LdapClient.prototype.destroy = function() { this.client.destroy(); }; | ||
43 | + LdapClient.prototype._search = promisify('search'); | ||
44 | + | ||
45 | + | ||
46 | + LdapClient.prototype.search = function(base, options, controls) { | ||
47 | + const client = this.client; | ||
48 | + | ||
49 | + return new Promise(function(resolve, reject) { | ||
50 | + const searchCallback = function(err, result) { | ||
51 | + const r = { | ||
52 | + entries: [], | ||
53 | + references: [], | ||
54 | + }; | ||
55 | + | ||
56 | + result.on('searchEntry', function(entry) { | ||
57 | + r.entries.push(entry); | ||
58 | + }); | ||
59 | + | ||
60 | + result.on('searchReference', function(reference) { | ||
61 | + r.references.push(reference); | ||
62 | + }); | ||
63 | + | ||
64 | + result.on('error', function(err) { | ||
65 | + reject(err); | ||
66 | + }); | ||
67 | + | ||
68 | + result.on('end', function(result) { | ||
69 | + if (result.status === 0) { | ||
70 | + resolve(r); | ||
71 | + } else { | ||
72 | + reject(new Error('non-zero status code: ' + result.status)); | ||
73 | + } | ||
74 | + }); | ||
75 | + }; | ||
76 | + | ||
77 | + const args = ([ base, options, controls, searchCallback ]) | ||
78 | + .filter(function(x) { return typeof x !== 'undefined'; }); | ||
79 | + | ||
80 | + client.search.apply(client, args); | ||
81 | + }); | ||
82 | + }; | ||
83 | + | ||
84 | + | ||
85 | + LdapClient.prototype.authenticate = function(base, cn, password) { | ||
86 | + const _this = this; | ||
87 | + | ||
88 | + return _this.bind('CN=' + cn + ',' + base, password).then( | ||
89 | + function() { | ||
90 | + return _this.search(base, { scope: 'sub', filter: '(cn=' + cn + ')' }).then(function(result) { | ||
91 | + return result.entries[0].object; | ||
92 | + }); | ||
93 | + }, | ||
94 | + function(err) { | ||
95 | + if (err.name === 'InvalidCredentialsError') { | ||
96 | + return null; | ||
97 | + } | ||
98 | + throw err; | ||
99 | + | ||
100 | + } | ||
101 | + ); | ||
102 | + }; | ||
103 | + | ||
104 | + | ||
105 | + LdapClient.prototype.authenticateUser = function(base, cn, password) { | ||
106 | + const dnRegex = new RegExp('^CN=([^,]+),' + base + '$'); | ||
107 | + | ||
108 | + return this.authenticate(base, cn, password).then(function(result) { | ||
109 | + if (result) { | ||
110 | + let groups = []; | ||
111 | + | ||
112 | + if (result.memberOf) { | ||
113 | + groups = result.memberOf | ||
114 | + .map(function(x) { return (x.match(dnRegex) || [])[1]; }) | ||
115 | + .filter(function(x) { return typeof x !== 'undefined'; }); | ||
116 | + } | ||
117 | + | ||
118 | + return { | ||
119 | + email: result.userPrincipalName, | ||
120 | + name: result.displayName, | ||
121 | + groups, | ||
122 | + }; | ||
123 | + | ||
124 | + } | ||
125 | + return null; | ||
126 | + | ||
127 | + }); | ||
128 | + }; | ||
129 | + | ||
130 | + | ||
131 | + const client = new LdapClient({ url: config.url }); | ||
132 | + | ||
133 | + app.beforeStart(async () => { | ||
134 | + const result = await client.bind(config.dn, config.password); | ||
135 | + const index = count++; | ||
136 | + app.coreLogger.info(`[egg-ldapjs] instance[${index}] status OK, client ready ${result}`); | ||
137 | + }); | ||
138 | + return client; | ||
139 | +} |
package-lock.json
0 → 100644
此 diff 太大无法显示。
package.json
0 → 100644
1 | +{ | ||
2 | + "name": "egg-ldapjs", | ||
3 | + "version": "1.0.0", | ||
4 | + "description": "openldap ldap", | ||
5 | + "eggPlugin": { | ||
6 | + "name": "ldapjs" | ||
7 | + }, | ||
8 | + "keywords": [ | ||
9 | + "egg", | ||
10 | + "eggPlugin", | ||
11 | + "egg-plugin", | ||
12 | + "ldap", | ||
13 | + "ldapjs" | ||
14 | + ], | ||
15 | + "dependencies": { | ||
16 | + "any-promise": "^1.3.0", | ||
17 | + "ldapjs": "^2.3.2" | ||
18 | + }, | ||
19 | + "devDependencies": { | ||
20 | + "autod": "^3.0.1", | ||
21 | + "autod-egg": "^1.1.0", | ||
22 | + "egg": "^2.16.0", | ||
23 | + "egg-bin": "^4.11.0", | ||
24 | + "egg-ci": "^1.11.0", | ||
25 | + "egg-mock": "^3.21.0", | ||
26 | + "eslint": "^5.13.0", | ||
27 | + "eslint-config-egg": "^7.1.0" | ||
28 | + }, | ||
29 | + "engines": { | ||
30 | + "node": ">=8.0.0" | ||
31 | + }, | ||
32 | + "scripts": { | ||
33 | + "test": "npm run lint -- --fix && egg-bin pkgfiles && npm run test-local", | ||
34 | + "test-local": "egg-bin test", | ||
35 | + "cov": "egg-bin cov", | ||
36 | + "lint": "eslint .", | ||
37 | + "ci": "egg-bin pkgfiles --check && npm run lint && npm run cov", | ||
38 | + "pkgfiles": "egg-bin pkgfiles", | ||
39 | + "autod": "autod" | ||
40 | + }, | ||
41 | + "files": [ | ||
42 | + "config", | ||
43 | + "app.js", | ||
44 | + "lib" | ||
45 | + ], | ||
46 | + "ci": { | ||
47 | + "version": "8, 10" | ||
48 | + }, | ||
49 | + "repository": { | ||
50 | + "type": "git", | ||
51 | + "url": "git+https://github.com/eggjs/egg-ldapjs.git" | ||
52 | + }, | ||
53 | + "bugs": { | ||
54 | + "url": "https://github.com/eggjs/egg/issues" | ||
55 | + }, | ||
56 | + "homepage": "https://github.com/eggjs/egg-ldapjs#readme", | ||
57 | + "author": "fan", | ||
58 | + "license": "MIT" | ||
59 | +} |
1 | +'use strict'; | ||
2 | + | ||
3 | +const Controller = require('egg').Controller; | ||
4 | + | ||
5 | +class HomeController extends Controller { | ||
6 | + async index() { | ||
7 | + this.ctx.body = 'hi, ' + this.app.plugins.ldapjs.name; | ||
8 | + const opts = { | ||
9 | + filter: '(objectclass=organizationalUnit)', | ||
10 | + scope: 'sub', | ||
11 | + attributes: [ 'dn', 'sn', 'cn', 'ou' ], | ||
12 | + }; | ||
13 | + console.log(this.app.ldapjs); | ||
14 | + const result = await this.app.ldapjs.search('dc=dodokeroro,dc=cn', opts); | ||
15 | + console.log('result::::', result); | ||
16 | + } | ||
17 | +} | ||
18 | + | ||
19 | +module.exports = HomeController; |
test/fixtures/apps/ldapjs-test/app/router.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +/** | ||
4 | + * egg-ldapjs default config | ||
5 | + * @member Config#ldapjs | ||
6 | + * @property {String} SOME_KEY - some description | ||
7 | + */ | ||
8 | +exports.ldapjs = { | ||
9 | + url: 'ldap://test.dodokeroro.cn:30007', | ||
10 | + dn: 'cn=admin,dc=dodokeroro,dc=cn', | ||
11 | + password: 'workai123', | ||
12 | +}; | ||
13 | + | ||
14 | +exports.keys = '123456'; |
test/fixtures/apps/ldapjs-test/package.json
0 → 100644
test/ldapjs.test.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +const mock = require('egg-mock'); | ||
4 | + | ||
5 | +describe('test/ldapjs.test.js', () => { | ||
6 | + let app; | ||
7 | + before(() => { | ||
8 | + app = mock.app({ | ||
9 | + baseDir: 'apps/ldapjs-test', | ||
10 | + }); | ||
11 | + return app.ready(); | ||
12 | + }); | ||
13 | + | ||
14 | + after(() => app.close()); | ||
15 | + afterEach(mock.restore); | ||
16 | + | ||
17 | + it('should GET /', () => { | ||
18 | + return app.httpRequest() | ||
19 | + .get('/') | ||
20 | + .expect('hi, ldapjs') | ||
21 | + .expect(200); | ||
22 | + }); | ||
23 | +}); |
请
注册
或
登录
后发表评论