123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- import {slug, getLdapUsername, getLdapEmail, getLdapUserUniqueID, syncUserData, addLdapUser} from './sync';
- import LDAP from './ldap';
- import { log_debug, log_info, log_warn, log_error } from './logger';
- function fallbackDefaultAccountSystem(bind, username, password) {
- if (typeof username === 'string') {
- if (username.indexOf('@') === -1) {
- username = {username};
- } else {
- username = {email: username};
- }
- }
- log_info('Fallback to default account system: ', username );
- const loginRequest = {
- user: username,
- password: {
- digest: SHA256(password),
- algorithm: 'sha-256',
- },
- };
- log_debug('Fallback options: ', loginRequest);
- return Accounts._runLoginHandlers(bind, loginRequest);
- }
- Accounts.registerLoginHandler('ldap', function(loginRequest) {
- if (!loginRequest.ldap || !loginRequest.ldapOptions) {
- return undefined;
- }
- log_info('Init LDAP login', loginRequest.username);
- if (LDAP.settings_get('LDAP_ENABLE') !== true) {
- return fallbackDefaultAccountSystem(this, loginRequest.username, loginRequest.ldapPass);
- }
- const self = this;
- const ldap = new LDAP();
- let ldapUser;
- try {
- ldap.connectSync();
- if (!!LDAP.settings_get('LDAP_USER_AUTHENTICATION')) {
- ldap.bindUserIfNecessary(loginRequest.username, loginRequest.ldapPass);
- ldapUser = ldap.searchUsersSync(loginRequest.username)[0];
- } else {
- const users = ldap.searchUsersSync(loginRequest.username);
- if (users.length !== 1) {
- log_info('Search returned', users.length, 'record(s) for', loginRequest.username);
- throw new Error('User not Found');
- }
- if (ldap.authSync(users[0].dn, loginRequest.ldapPass) === true) {
- if (ldap.isUserInGroup(loginRequest.username, users[0])) {
- ldapUser = users[0];
- } else {
- throw new Error('User not in a valid group');
- }
- } else {
- log_info('Wrong password for', loginRequest.username);
- }
- }
- } catch (error) {
- log_error(error);
- }
- if (!ldapUser) {
- if (LDAP.settings_get('LDAP_LOGIN_FALLBACK') === true) {
- return fallbackDefaultAccountSystem(self, loginRequest.username, loginRequest.ldapPass);
- }
- throw new Meteor.Error('LDAP-login-error', `LDAP Authentication failed with provided username [${ loginRequest.username }]`);
- }
- // Look to see if user already exists
- let userQuery;
- const Unique_Identifier_Field = getLdapUserUniqueID(ldapUser);
- let user;
- // Attempt to find user by unique identifier
- if (Unique_Identifier_Field) {
- userQuery = {
- 'services.ldap.id': Unique_Identifier_Field.value,
- };
- log_info('Querying user');
- log_debug('userQuery', userQuery);
- user = Meteor.users.findOne(userQuery);
- }
- // Attempt to find user by username
- let username;
- let email;
- if (LDAP.settings_get('LDAP_USERNAME_FIELD') !== '') {
- username = slug(getLdapUsername(ldapUser));
- } else {
- username = slug(loginRequest.username);
- }
- if(LDAP.settings_get('LDAP_EMAIL_FIELD') !== '') {
- email = getLdapEmail(ldapUser);
- }
- if (!user) {
- if(email && LDAP.settings_get('LDAP_EMAIL_MATCH_REQUIRE') === true) {
- if(LDAP.settings_get('LDAP_EMAIL_MATCH_VERIFIED') === true) {
- userQuery = {
- '_id' : username,
- 'emails.0.address' : email,
- 'emails.0.verified' : true
- };
- } else {
- userQuery = {
- '_id' : username,
- 'emails.0.address' : email
- };
- }
- } else {
- userQuery = {
- username
- };
- }
- log_debug('userQuery', userQuery);
- user = Meteor.users.findOne(userQuery);
- }
- // Attempt to find user by e-mail address only
- if (!user && email && LDAP.settings_get('LDAP_EMAIL_MATCH_ENABLE') === true) {
- log_info('No user exists with username', username, '- attempting to find by e-mail address instead');
- if(LDAP.settings_get('LDAP_EMAIL_MATCH_VERIFIED') === true) {
- userQuery = {
- 'emails.0.address': email,
- 'emails.0.verified' : true
- };
- } else {
- userQuery = {
- 'emails.0.address' : email
- };
- }
- log_debug('userQuery', userQuery);
- user = Meteor.users.findOne(userQuery);
- }
- // Login user if they exist
- if (user) {
- if (user.authenticationMethod !== 'ldap' && LDAP.settings_get('LDAP_MERGE_EXISTING_USERS') !== true) {
- log_info('User exists without "authenticationMethod : ldap"');
- throw new Meteor.Error('LDAP-login-error', `LDAP Authentication succeded, but there's already a matching Wekan account in MongoDB`);
- }
- log_info('Logging user');
- const stampedToken = Accounts._generateStampedLoginToken();
- const update_data = {
- $push: {
- 'services.resume.loginTokens': Accounts._hashStampedToken(stampedToken),
- },
- };
- if( LDAP.settings_get('LDAP_SYNC_GROUP_ROLES') === true ) {
- log_debug('Updating Groups/Roles');
- const groups = ldap.getUserGroups(username, ldapUser);
- if( groups.length > 0 ) {
- Roles.setUserRoles(user._id, groups );
- log_info(`Updated roles to:${ groups.join(',')}`);
- }
- }
- Meteor.users.update(user._id, update_data );
- syncUserData(user, ldapUser);
- if (LDAP.settings_get('LDAP_LOGIN_FALLBACK') === true) {
- Accounts.setPassword(user._id, loginRequest.ldapPass, {logout: false});
- }
- return {
- userId: user._id,
- token: stampedToken.token,
- };
- }
- // Create new user
- log_info('User does not exist, creating', username);
- if (LDAP.settings_get('LDAP_USERNAME_FIELD') === '') {
- username = undefined;
- }
- if (LDAP.settings_get('LDAP_LOGIN_FALLBACK') !== true) {
- loginRequest.ldapPass = undefined;
- }
- const result = addLdapUser(ldapUser, username, loginRequest.ldapPass);
- if( LDAP.settings_get('LDAP_SYNC_GROUP_ROLES') === true ) {
- const groups = ldap.getUserGroups(username, ldapUser);
- if( groups.length > 0 ) {
- Roles.setUserRoles(result.userId, groups );
- log_info(`Set roles to:${ groups.join(',')}`);
- }
- }
- if (result instanceof Error) {
- throw result;
- }
- return result;
- });
|