mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-24 21:15:51 +01:00
refactor: relocate verdaccio-active-directory plugin (#1981)
This commit is contained in:
parent
c5f2b07364
commit
3a93da454f
3
packages/plugins/active-directory/.babelrc
Normal file
3
packages/plugins/active-directory/.babelrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../../.babelrc"
|
||||
}
|
214
packages/plugins/active-directory/CHANGELOG.md
Normal file
214
packages/plugins/active-directory/CHANGELOG.md
Normal file
@ -0,0 +1,214 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [9.7.2](https://github.com/verdaccio/monorepo/compare/v9.7.1...v9.7.2) (2020-07-20)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [9.7.1](https://github.com/verdaccio/monorepo/compare/v9.7.0...v9.7.1) (2020-07-10)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [9.7.0](https://github.com/verdaccio/monorepo/compare/v9.6.1...v9.7.0) (2020-06-24)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [9.6.1](https://github.com/verdaccio/monorepo/compare/v9.6.0...v9.6.1) (2020-06-07)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [9.5.0](https://github.com/verdaccio/monorepo/compare/v9.4.1...v9.5.0) (2020-05-02)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [9.4.0](https://github.com/verdaccio/monorepo/compare/v9.3.4...v9.4.0) (2020-03-21)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [9.3.2](https://github.com/verdaccio/monorepo/compare/v9.3.1...v9.3.2) (2020-03-08)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [9.3.1](https://github.com/verdaccio/monorepo/compare/v9.3.0...v9.3.1) (2020-02-23)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [9.3.0](https://github.com/verdaccio/monorepo/compare/v9.2.0...v9.3.0) (2020-01-29)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [9.0.0](https://github.com/verdaccio/monorepo/compare/v8.5.3...v9.0.0) (2020-01-07)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.5.2](https://github.com/verdaccio/monorepo/compare/v8.5.1...v8.5.2) (2019-12-25)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.5.1](https://github.com/verdaccio/monorepo/compare/v8.5.0...v8.5.1) (2019-12-24)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.5.0](https://github.com/verdaccio/monorepo/compare/v8.4.2...v8.5.0) (2019-12-22)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.4.2](https://github.com/verdaccio/monorepo/compare/v8.4.1...v8.4.2) (2019-11-23)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.4.1](https://github.com/verdaccio/monorepo/compare/v8.4.0...v8.4.1) (2019-11-22)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.4.0](https://github.com/verdaccio/monorepo/compare/v8.3.0...v8.4.0) (2019-11-22)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.3.0](https://github.com/verdaccio/monorepo/compare/v8.2.0...v8.3.0) (2019-10-27)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.2.0](https://github.com/verdaccio/monorepo/compare/v8.2.0-next.0...v8.2.0) (2019-10-23)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.2.0-next.0](https://github.com/verdaccio/monorepo/compare/v8.1.4...v8.2.0-next.0) (2019-10-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fixed lint errors ([5e677f7](https://github.com/verdaccio/monorepo/commit/5e677f7))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.1.2](https://github.com/verdaccio/monorepo/compare/v8.1.1...v8.1.2) (2019-09-29)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.1.1](https://github.com/verdaccio/monorepo/compare/v8.1.0...v8.1.1) (2019-09-26)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.1.0](https://github.com/verdaccio/monorepo/compare/v8.0.1-next.1...v8.1.0) (2019-09-07)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.0.1-next.1](https://github.com/verdaccio/monorepo/compare/v8.0.1-next.0...v8.0.1-next.1) (2019-08-29)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.0.1-next.0](https://github.com/verdaccio/monorepo/compare/v8.0.0...v8.0.1-next.0) (2019-08-29)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0](https://github.com/verdaccio/monorepo/compare/v8.0.0-next.4...v8.0.0) (2019-08-22)
|
||||
|
||||
**Note:** Version bump only for package @verdaccio/active-directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-next.4](https://github.com/verdaccio/monorepo/compare/v8.0.0-next.3...v8.0.0-next.4) (2019-08-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **active-directory:** create @verdaccio/active-directory plugin ([b04ef0d](https://github.com/verdaccio/monorepo/commit/b04ef0d))
|
21
packages/plugins/active-directory/LICENSE
Normal file
21
packages/plugins/active-directory/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Verdaccio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
34
packages/plugins/active-directory/README.md
Normal file
34
packages/plugins/active-directory/README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# @verdaccio/active-directory
|
||||
|
||||
Active Directory authentication plugin for Verdaccio
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install -g @verdaccio/active-directory
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
This settings can be set in `config.yaml`. All fields are mandatory except `groupName`, which is optional, to add security group(s). Also, this optional field can be a single string or a list of strings. Take care that, when defining `groupName` key, the user that will be authenticating must be in, at least, one of the groups defined, to authenticate successfully.
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
activedirectory:
|
||||
url: 'ldap://localhost'
|
||||
baseDN: 'dc=local,dc=host'
|
||||
domainSuffix: 'local.host'
|
||||
# groupName: 'singleGroup' # optional, single group syntax
|
||||
# groupName: # optional, multiple groups syntax
|
||||
# - 'group1'
|
||||
# - 'group2'
|
||||
```
|
||||
|
||||
## Inspiration
|
||||
|
||||
This plugin is based on [verdaccio-activedirectory](https://github.com/nowhammies/verdaccio-activedirectory), which is based on [siponia-activedirectory](https://github.com/ela-compil/sinopia-activedirectory).
|
||||
Thanks to [Doug Dennie](https://github.com/nowhammies) and [Ela-compil sp. z o. o.](https://github.com/ela-compil) for making this possible.
|
||||
|
||||
## License
|
||||
|
||||
@verdaccio/active-directory is an open source project with [MIT license](LICENSE)
|
5
packages/plugins/active-directory/jest.config.js
Normal file
5
packages/plugins/active-directory/jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
const config = require('../../../jest/config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
collectCoverage: true,
|
||||
});
|
47
packages/plugins/active-directory/package.json
Normal file
47
packages/plugins/active-directory/package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "@verdaccio/active-directory",
|
||||
"version": "10.0.0-beta",
|
||||
"description": "Active Directory authentication plugin for Verdaccio",
|
||||
"keywords": [
|
||||
"verdaccio",
|
||||
"active-directory",
|
||||
"auth",
|
||||
"plugin"
|
||||
],
|
||||
"author": "Sergio Herrera <sergio@sergiohgz.eu>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": {
|
||||
"type": "https",
|
||||
"url": "https://github.com/verdaccio/verdaccio",
|
||||
"directory": "packages/plugins/active-directory"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/verdaccio/verdaccio/issues"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:*",
|
||||
"activedirectory2": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/activedirectory2": "^1.2.1",
|
||||
"@verdaccio/types": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||
"build": "pnpm run build:js && pnpm run build:types",
|
||||
"test": "cross-env NODE_ENV=test BABEL_ENV=test jest"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/verdaccio"
|
||||
}
|
||||
}
|
86
packages/plugins/active-directory/src/active-directory.ts
Normal file
86
packages/plugins/active-directory/src/active-directory.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import { getForbidden, getInternalError, getUnauthorized } from '@verdaccio/commons-api';
|
||||
import { Callback, IPluginAuth, Logger } from '@verdaccio/types';
|
||||
import ActiveDirectory from 'activedirectory2';
|
||||
|
||||
export const NotAuthMessage = 'AD - Active Directory authentication failed';
|
||||
|
||||
export interface ActiveDirectoryConfig {
|
||||
url: string;
|
||||
baseDN: string;
|
||||
domainSuffix: string;
|
||||
groupName?: string | string[];
|
||||
}
|
||||
|
||||
class ActiveDirectoryPlugin implements IPluginAuth<ActiveDirectoryConfig> {
|
||||
private config: ActiveDirectoryConfig;
|
||||
private logger: Logger;
|
||||
|
||||
public constructor(config: ActiveDirectoryConfig, opts: { logger: Logger }) {
|
||||
this.config = config;
|
||||
this.logger = opts.logger;
|
||||
}
|
||||
|
||||
public authenticate(user: string, password: string, cb: Callback): void {
|
||||
const username = `${user}@${this.config.domainSuffix}`;
|
||||
|
||||
const connectionConfig = {
|
||||
...this.config,
|
||||
domainSuffix: undefined,
|
||||
username,
|
||||
password,
|
||||
};
|
||||
|
||||
const connection = new ActiveDirectory(connectionConfig);
|
||||
|
||||
connection.authenticate(username, password, (err, isAuthenticated): void => {
|
||||
if (err) {
|
||||
this.logger.warn(`AD - Active Directory authentication failed with error: ${err}`);
|
||||
return cb(getInternalError(err));
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
this.logger.warn(NotAuthMessage);
|
||||
return cb(getUnauthorized(NotAuthMessage));
|
||||
}
|
||||
|
||||
const { groupName } = this.config;
|
||||
if (!groupName) {
|
||||
this.logger.info('AD - Active Directory authentication succeeded');
|
||||
cb(null, [user]);
|
||||
} else {
|
||||
connection.getGroupMembershipForUser(username, (err, groups: object[]): void => {
|
||||
if (err) {
|
||||
this.logger.warn(`AD - Active Directory group check failed with error: ${err}`);
|
||||
return cb(getInternalError((err as unknown) as string));
|
||||
}
|
||||
|
||||
const requestedGroups = Array.isArray(groupName) ? groupName : [groupName];
|
||||
const matchingGroups = requestedGroups.filter((requestedGroup): boolean =>
|
||||
groups.some(
|
||||
(group: { cn?: string; dn?: string }): boolean =>
|
||||
requestedGroup === group.cn || requestedGroup === group.dn
|
||||
)
|
||||
);
|
||||
|
||||
if (matchingGroups.length <= 0) {
|
||||
const notMemberMessage = `AD - User ${user} is not member of group(s): ${requestedGroups.join(
|
||||
', '
|
||||
)}`;
|
||||
|
||||
this.logger.warn(notMemberMessage);
|
||||
cb(getForbidden(notMemberMessage));
|
||||
} else {
|
||||
this.logger.info(
|
||||
`AD - Active Directory authentication succeeded in group(s): ${matchingGroups.join(
|
||||
', '
|
||||
)}`
|
||||
);
|
||||
cb(null, [...matchingGroups, user]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default ActiveDirectoryPlugin;
|
5
packages/plugins/active-directory/src/index.ts
Normal file
5
packages/plugins/active-directory/src/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import ActiveDirectory from './active-directory';
|
||||
|
||||
export { ActiveDirectory };
|
||||
|
||||
export default ActiveDirectory;
|
14
packages/plugins/active-directory/tests/__mocks__/Logger.ts
Normal file
14
packages/plugins/active-directory/tests/__mocks__/Logger.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Logger } from '@verdaccio/types';
|
||||
|
||||
const logger: Logger = {
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
fatal: jest.fn(),
|
||||
info: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
child: jest.fn(),
|
||||
http: jest.fn(),
|
||||
trace: jest.fn(),
|
||||
};
|
||||
|
||||
export default logger;
|
161
packages/plugins/active-directory/tests/active-directory.test.ts
Normal file
161
packages/plugins/active-directory/tests/active-directory.test.ts
Normal file
@ -0,0 +1,161 @@
|
||||
import ActiveDirectory from 'activedirectory2';
|
||||
import { HTTP_STATUS } from '@verdaccio/commons-api';
|
||||
|
||||
import ActiveDirectoryPlugin, { NotAuthMessage } from '../src/active-directory';
|
||||
|
||||
// eslint-disable-next-line jest/no-mocks-import
|
||||
import logger from './__mocks__/Logger';
|
||||
|
||||
describe('Active Directory Plugin', () => {
|
||||
let adPlugin;
|
||||
let adPluginSingleGroup;
|
||||
let adPluginMultiGroups;
|
||||
|
||||
const config = {
|
||||
url: 'ldap://localhost',
|
||||
baseDN: 'dc=local,dc=host',
|
||||
domainSuffix: 'local.host',
|
||||
};
|
||||
|
||||
const configSingleGroup = {
|
||||
...config,
|
||||
groupName: 'singleGroup',
|
||||
};
|
||||
|
||||
const configMultiGroups = {
|
||||
...config,
|
||||
groupName: ['group1', 'group2', 'group3'],
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
adPlugin = new ActiveDirectoryPlugin(config, { logger });
|
||||
adPluginSingleGroup = new ActiveDirectoryPlugin(configSingleGroup, { logger });
|
||||
adPluginMultiGroups = new ActiveDirectoryPlugin(configMultiGroups, { logger });
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
});
|
||||
|
||||
test('get error when connection fails', (done) => {
|
||||
const errorMessage = 'Unknown error';
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(errorMessage, undefined));
|
||||
|
||||
adPlugin.authenticate('', '', (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(logger.warn).toHaveBeenCalled();
|
||||
expect(error.code).toBe(HTTP_STATUS.INTERNAL_ERROR);
|
||||
expect(error.message).toBe(errorMessage);
|
||||
expect(authUser).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('get error when not authenticated satisfactory', (done) => {
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, false));
|
||||
|
||||
adPlugin.authenticate('', '', (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(logger.warn).toHaveBeenCalledWith(NotAuthMessage);
|
||||
expect(error.code).toBe(HTTP_STATUS.UNAUTHORIZED);
|
||||
expect(error.message).toBe(NotAuthMessage);
|
||||
expect(authUser).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('connect satisfactory without groups', (done) => {
|
||||
const user = 'user';
|
||||
const password = 'password';
|
||||
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
|
||||
|
||||
adPlugin.authenticate(user, password, (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(logger.info).toHaveBeenCalled();
|
||||
expect(error).toBeNull();
|
||||
expect(authUser).toStrictEqual([user]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('get error when getting groups for user', (done) => {
|
||||
const errorMessage = 'Unknown error retrieving groups';
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
|
||||
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
|
||||
cb((errorMessage as unknown) as object, null)
|
||||
) as jest.Mock;
|
||||
|
||||
adPluginSingleGroup.authenticate('', '', (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(ActiveDirectory.prototype.getGroupMembershipForUser).toHaveBeenCalled();
|
||||
expect(logger.warn).toHaveBeenCalled();
|
||||
expect(error.code).toBe(HTTP_STATUS.INTERNAL_ERROR);
|
||||
expect(error.message).toBe(errorMessage);
|
||||
expect(authUser).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('get error when user groups do not match', (done) => {
|
||||
const user = 'user';
|
||||
const password = 'password';
|
||||
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
|
||||
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
|
||||
cb(null, [{ cn: 'notMatchGroup' }])
|
||||
) as jest.Mock;
|
||||
|
||||
adPluginSingleGroup.authenticate(user, password, (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(ActiveDirectory.prototype.getGroupMembershipForUser).toHaveBeenCalled();
|
||||
expect(logger.warn).toHaveBeenCalled();
|
||||
expect(error.code).toBe(HTTP_STATUS.FORBIDDEN);
|
||||
expect(error.message).toBe(
|
||||
`AD - User ${user} is not member of group(s): ${configSingleGroup.groupName}`
|
||||
);
|
||||
expect(authUser).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('connect satisfactory when connection has only one group defined', (done) => {
|
||||
const { groupName } = configSingleGroup;
|
||||
const user = 'user';
|
||||
const password = 'password';
|
||||
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
|
||||
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
|
||||
cb(null, [{ cn: groupName }])
|
||||
) as jest.Mock;
|
||||
|
||||
adPluginSingleGroup.authenticate(user, password, (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(ActiveDirectory.prototype.getGroupMembershipForUser).toHaveBeenCalled();
|
||||
expect(logger.info).toHaveBeenCalled();
|
||||
expect(error).toBeNull();
|
||||
expect(authUser).toStrictEqual([groupName, user]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('connect satisfactory when connection has multiple groups defined', (done) => {
|
||||
const [, group2, group3] = configMultiGroups.groupName;
|
||||
const user = 'user';
|
||||
const password = 'password';
|
||||
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
|
||||
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
|
||||
cb(null, [{ cn: group2 }, { dn: group3 }])
|
||||
) as jest.Mock;
|
||||
|
||||
adPluginMultiGroups.authenticate(user, password, (error, authUser) => {
|
||||
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
|
||||
expect(ActiveDirectory.prototype.getGroupMembershipForUser).toHaveBeenCalled();
|
||||
expect(logger.info).toHaveBeenCalled();
|
||||
expect(error).toBeNull();
|
||||
expect(authUser).toStrictEqual([group2, group3, user]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
9
packages/plugins/active-directory/tsconfig.build.json
Normal file
9
packages/plugins/active-directory/tsconfig.build.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./build"
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
}
|
20
packages/plugins/active-directory/tsconfig.json
Normal file
20
packages/plugins/active-directory/tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.reference.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./build"
|
||||
},
|
||||
"include": ["src/**/*", "types/*.d.ts"],
|
||||
"exclude": ["src/**/*.test.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../core/commons-api"
|
||||
},
|
||||
{
|
||||
"path": "../../core/streams"
|
||||
},
|
||||
{
|
||||
"path": "../../core/types"
|
||||
}
|
||||
]
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
"license": "MIT",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"type": "https",
|
||||
"url": "https://github.com/verdaccio/verdaccio",
|
||||
"directory": "packages/plugins/audit"
|
||||
},
|
||||
|
125
pnpm-lock.yaml
generated
125
pnpm-lock.yaml
generated
@ -519,6 +519,18 @@ importers:
|
||||
core-js: ^3.6.5
|
||||
lodash: ^4.17.20
|
||||
selfsigned: 1.10.7
|
||||
packages/plugins/active-directory:
|
||||
dependencies:
|
||||
'@verdaccio/commons-api': 'link:../../core/commons-api'
|
||||
activedirectory2: 1.3.0
|
||||
devDependencies:
|
||||
'@types/activedirectory2': 1.2.2
|
||||
'@verdaccio/types': 'link:../../core/types'
|
||||
specifiers:
|
||||
'@types/activedirectory2': ^1.2.1
|
||||
'@verdaccio/commons-api': 'workspace:*'
|
||||
'@verdaccio/types': 'workspace:*'
|
||||
activedirectory2: ^1.3.0
|
||||
packages/plugins/audit:
|
||||
dependencies:
|
||||
express: 4.17.1
|
||||
@ -5753,6 +5765,12 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-M2BiThcbxMxSKX8W4z5u9jKZn6datnM3+FpEU+eYw0//l31E2xhqi7vTAuJ/Sf0P3yhp66SDJgPu3bRRpvrdQQ==
|
||||
/@types/activedirectory2/1.2.2:
|
||||
dependencies:
|
||||
'@types/ldapjs': 1.0.9
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-YVvlqf7hemxSS7D+sG8FZO1ClrSScniOtwLoyA+sR8193U9PCBTlpo1JUZEcgHNA+rrIHMrsBHP3rbH3gtV0pg==
|
||||
/@types/async/3.2.3:
|
||||
dev: true
|
||||
resolution:
|
||||
@ -5961,6 +5979,12 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
|
||||
/@types/ldapjs/1.0.9:
|
||||
dependencies:
|
||||
'@types/node': 14.10.0
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-3PvY7Drp1zoLbcGlothCAkoc5o6Jp9KvUPwHadlHyKp3yPvyeIh7w2zQc9UXMzgDRkoeGXUEODtbEs5XCh9ZyA==
|
||||
/@types/lodash.sample/4.2.6:
|
||||
dependencies:
|
||||
'@types/lodash': 4.14.160
|
||||
@ -6021,7 +6045,6 @@ packages:
|
||||
resolution:
|
||||
integrity: sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==
|
||||
/@types/node/14.10.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-SOIyrdADB4cq6eY1F+9iU48iIomFAPltu11LCvA9PKcyEwHadjCFzNVPotAR+oEJA0bCP4Xvvgy+vwu1ZjVh8g==
|
||||
/@types/node/14.6.0:
|
||||
@ -6699,6 +6722,10 @@ packages:
|
||||
node: '>=6'
|
||||
resolution:
|
||||
integrity: sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==
|
||||
/abstract-logging/1.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-i33q/TEFWbwo93ck3RuzAXcnjBs=
|
||||
/accepts/1.3.7:
|
||||
dependencies:
|
||||
mime-types: 2.1.27
|
||||
@ -6773,6 +6800,17 @@ packages:
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
|
||||
/activedirectory2/1.3.0:
|
||||
dependencies:
|
||||
abstract-logging: 1.0.0
|
||||
async: 2.6.3
|
||||
ldapjs: 1.0.2
|
||||
merge-options: 1.0.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4.0'
|
||||
resolution:
|
||||
integrity: sha512-0cj+/uLgF22UcqH8/Ez9nHjF2+1+dpjFjofsjIq7WGPNwsVAJyEETdmxjLKYQaU1mK2gZsQmo1Ip4E27CyoBeQ==
|
||||
/add-stream/1.0.0:
|
||||
dev: true
|
||||
resolution:
|
||||
@ -7139,11 +7177,21 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
|
||||
/asn1/0.2.3:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=
|
||||
/asn1/0.2.4:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
resolution:
|
||||
integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
|
||||
/assert-plus/0.1.5:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.8'
|
||||
resolution:
|
||||
integrity: sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=
|
||||
/assert-plus/1.0.0:
|
||||
engines:
|
||||
node: '>=0.8'
|
||||
@ -7618,6 +7666,14 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-MasayLEpNjRj41s+u2n038+6eUc=
|
||||
/backoff/2.5.0:
|
||||
dependencies:
|
||||
precond: 0.2.3
|
||||
dev: false
|
||||
engines:
|
||||
node: '>= 0.6'
|
||||
resolution:
|
||||
integrity: sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=
|
||||
/bail/1.0.5:
|
||||
dev: false
|
||||
resolution:
|
||||
@ -11530,6 +11586,12 @@ packages:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==
|
||||
/extsprintf/1.2.0:
|
||||
dev: false
|
||||
engines:
|
||||
'0': node >=0.6.0
|
||||
resolution:
|
||||
integrity: sha1-WtlGwi9bMrp/jNdCZxHG6KP8JSk=
|
||||
/extsprintf/1.3.0:
|
||||
engines:
|
||||
'0': node >=0.6.0
|
||||
@ -16008,6 +16070,33 @@ packages:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==
|
||||
/ldap-filter/0.2.2:
|
||||
dependencies:
|
||||
assert-plus: 0.1.5
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.8'
|
||||
resolution:
|
||||
integrity: sha1-8rhCvguG2jNSeYUFsx68rlkNd9A=
|
||||
/ldapjs/1.0.2:
|
||||
dependencies:
|
||||
asn1: 0.2.3
|
||||
assert-plus: 1.0.0
|
||||
backoff: 2.5.0
|
||||
bunyan: 1.8.14
|
||||
dashdash: 1.14.1
|
||||
ldap-filter: 0.2.2
|
||||
once: 1.4.0
|
||||
vasync: 1.6.4
|
||||
verror: 1.10.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10'
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
dtrace-provider: 0.8.8
|
||||
resolution:
|
||||
integrity: sha1-VE/3Ayt7g8aPBwEyjZKXqmlDQPk=
|
||||
/level-codec/9.0.2:
|
||||
dependencies:
|
||||
buffer: 5.6.0
|
||||
@ -17016,6 +17105,14 @@ packages:
|
||||
/merge-descriptors/1.0.1:
|
||||
resolution:
|
||||
integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
|
||||
/merge-options/1.0.1:
|
||||
dependencies:
|
||||
is-plain-obj: 1.1.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==
|
||||
/merge-stream/2.0.0:
|
||||
resolution:
|
||||
integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||
@ -17193,6 +17290,7 @@ packages:
|
||||
resolution:
|
||||
integrity: sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
|
||||
/minimist/0.0.8:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
|
||||
/minimist/0.2.1:
|
||||
@ -17265,6 +17363,7 @@ packages:
|
||||
/mkdirp/0.5.1:
|
||||
dependencies:
|
||||
minimist: 0.0.8
|
||||
dev: true
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
||||
@ -17343,7 +17442,7 @@ packages:
|
||||
integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
||||
/mv/2.1.1:
|
||||
dependencies:
|
||||
mkdirp: 0.5.1
|
||||
mkdirp: 0.5.5
|
||||
ncp: 2.0.0
|
||||
rimraf: 2.4.5
|
||||
engines:
|
||||
@ -19154,6 +19253,12 @@ packages:
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw==
|
||||
/precond/0.2.3:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>= 0.6'
|
||||
resolution:
|
||||
integrity: sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=
|
||||
/preferred-pm/3.0.2:
|
||||
dependencies:
|
||||
find-up: 5.0.0
|
||||
@ -23159,6 +23264,14 @@ packages:
|
||||
node: '>= 0.8'
|
||||
resolution:
|
||||
integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||
/vasync/1.6.4:
|
||||
dependencies:
|
||||
verror: 1.6.0
|
||||
dev: false
|
||||
engines:
|
||||
'0': node >=0.6.0
|
||||
resolution:
|
||||
integrity: sha1-3+k2Fq0OeugBszKp2Iv8XNyOHR8=
|
||||
/vendors/1.0.4:
|
||||
dev: false
|
||||
resolution:
|
||||
@ -23314,6 +23427,14 @@ packages:
|
||||
'0': node >=0.6.0
|
||||
resolution:
|
||||
integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
|
||||
/verror/1.6.0:
|
||||
dependencies:
|
||||
extsprintf: 1.2.0
|
||||
dev: false
|
||||
engines:
|
||||
'0': node >=0.6.0
|
||||
resolution:
|
||||
integrity: sha1-fROyex+swuLakEBetepuW90lLqU=
|
||||
/vfile-location/2.0.6:
|
||||
dev: false
|
||||
resolution:
|
||||
|
Loading…
Reference in New Issue
Block a user