提交 4665e1bfca61ce154bc55c6d4291547291de08f4

作者 fanwh
0 个父辈

no message

  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 +};
... ...
  1 +coverage
... ...
  1 +{
  2 + "extends": "eslint-config-egg"
  3 +}
... ...
  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. -->
... ...
  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 }}
... ...
  1 +logs/
  2 +npm-debug.log
  3 +node_modules/
  4 +coverage/
  5 +.idea/
  6 +run/
  7 +.DS_Store
  8 +*.swp
  9 +
... ...
  1 +
  2 +language: node_js
  3 +node_js:
  4 + - '8'
  5 + - '10'
  6 +before_install:
  7 + - npm i npminstall -g
  8 +install:
  9 + - npminstall
  10 +script:
  11 + - npm run ci
  12 +after_script:
  13 + - npminstall codecov && codecov
... ...
  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.
... ...
  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)
... ...
  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)
... ...
  1 +'use strict';
  2 +
  3 +const ldapjs = require('./lib/ldap');
  4 +
  5 +module.exports = app => {
  6 + if (app.config.ldapjs) ldapjs(app);
  7 +};
... ...
  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
... ...
  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 +};
... ...
  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 +}
... ...
此 diff 太大无法显示。
  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;
... ...
  1 +'use strict';
  2 +
  3 +module.exports = app => {
  4 + const { router, controller } = app;
  5 +
  6 + router.get('/', controller.home.index);
  7 +};
... ...
  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';
... ...
  1 +{
  2 + "name": "ldapjs-test",
  3 + "version": "0.0.1"
  4 +}
\ No newline at end of file
... ...
  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 +});
... ...
注册登录 后发表评论