Add i18n strings and rename some files

pull/2167/head
Rodrigo Nascimento 10 years ago
parent 3c7c6c2e5a
commit 4da99981af
  1. 37
      i18n/en.i18n.json
  2. 45
      packages/rocketchat-ldap/client/loginHelper.js
  3. 172
      packages/rocketchat-ldap/server/loginHandler.js
  4. 38
      packages/rocketchat-ldap/server/settings.coffee

@ -263,25 +263,40 @@
"Layout_Sidenav_Footer_description" : "Footer size is 260 x 70px",
"Layout_Terms_of_Service" : "Terms of Service",
"LDAP" : "LDAP",
"LDAP_Bind_Search" : "Bind Search",
"LDAP_Bind_Search_Description" : "A piece of JSON that governs bind and connection info and is of the form {\"filter\": \"(&(objectCategory=person)(objectclass=user)(memberOf=CN=ROCKET_ACCESS,CN=Users,DC=domain,DC=com)(sAMAccountName=#{username}))\", \"scope\": \"sub\", \"userDN\": \"rocket.service@domain.com\", \"password\": \"urpass\"}",
"LDAP_CA_Cert" : "CA Cert",
"LDAP_Custom_Domain_Search" : "Custom Domain Search",
"LDAP_Custom_Domain_Search_Description" : "A piece of JSON that governs bind and connection info and is of the form:<br/> <code>{\"filter\": \"(&(objectCategory=person)(objectclass=user)(memberOf=CN=ROCKET_ACCESS,CN=Users,DC=domain,DC=com)(sAMAccountName=#{username}))\", \"scope\": \"sub\", \"userDN\": \"rocket.service@domain.com\", \"password\": \"urpass\"}</code>",
"LDAP_Default_Domain" : "Default Domain",
"LDAP_Description" : "LDAP is a hierarchical database that many companies use to provide single sign on - a facility for sharing one password between multiple sites and services. For advanced configuration information and examples, please consult our wiki: https://github.com/RocketChat/Rocket.Chat/wiki/LDAP-Authentication.",
"LDAP_DN" : "Distinguished Name (DN)",
"LDAP_DN_Description" : "Search root; example: dc=domain,dc=com",
"LDAP_Enable" : "Enable LDAP",
"LDAP_Domain_Base" : "Domain Base",
"LDAP_Domain_Base_Description" : "The fully qualified Distinguished Name (DN) of an LDAP subtree you want to search for users and groups. You can add as many as you like; however, each group must be defined in the same domain base as the users that belong to it. If you specify restricted user groups, only users that belong to those groups will be in scope. We recommend that you specify the top level of your LDAP directory tree as your domain base and use restricted user groups to control access.",
"LDAP_Domain_Search_Object_Category" : "Domain Search Object Category",
"LDAP_Domain_Search_Object_Category_Description" : "The *objectCategory* that identify your users. <br/>E.g. `person`, etc.",
"LDAP_Domain_Search_Object_Class" : "Domain Search Object Class",
"LDAP_Domain_Search_Object_Class_Description" : "The *objectclass* that identify your users. <br/>E.g. `organizationalPerson`, `user`, `inetOrgPerson`, etc.",
"LDAP_Domain_Search_Password" : "Domain Search Password",
"LDAP_Domain_Search_Password_Description" : "The password for the domain search user.",
"LDAP_Domain_Search_User" : "Domain Search User",
"LDAP_Domain_Search_User_Description" : "The LDAP user that performs user lookups to authenticate other users when they sign in. <br/>This is typically a service account created specifically for third-party integrations. Use a fully qualified name, such as `cn=Administrator,cn=Users,dc=Example,dc=com`.",
"LDAP_Domain_Search_User_ID" : "Domain Search User ID",
"LDAP_Domain_Search_User_ID_Description" : "The LDAP attribute that identifies the LDAP user who attempts authentication. This field should be `sAMAccountName` for most Active Directory installations, but it may be `uid` for other LDAP solutions, such as OpenLDAP. You can use `mail` to identify users by e-mail or whatever attribute you want.",
"LDAP_Enable" : "Enable",
"LDAP_Enable_Description" : "Attempt to utilize LDAP for authentication.",
"LDAP_Port" : "LDAP Port",
"LDAP_Port_Description" : "Port to access LDAP on; eg: 389",
"LDAP_Encryption" : "Encryption",
"LDAP_Encryption_Description" : "The encryption method used to secure communications to the LDAP server. Examples include `plain` (no encryption), `SSL/LDAPS` (encrypted from the start), and `StartTLS` (upgrade to encrypted communication once connected).",
"LDAP_Host" : "Host",
"LDAP_Host_Description": "The LDAP host, e.g. `ldap.example.com` or `10.0.0.30`.",
"LDAP_Port" : "Port",
"LDAP_Port_Description" : "Port to access LDAP. eg: `389` or `636` for LDAPS",
"LDAP_Reject_Unauthorized" : "Reject Unauthorized",
"LDAP_Restricted_User_Groups" : "Restricted User Groups",
"LDAP_Restricted_User_Groups_Description" : "If specified, only users in these groups will be allowed to log in. You only need to specify the common names (CNs) of the groups, and you can add as many groups as you like. If no groups are specified, all users within the scope of the specified domain base will be able to sign in. E.g `cn=ROCKET_CHAT,ou=General Groups`.",
"LDAP_Sync_User_Data" : "Sync Data",
"LDAP_Sync_User_Data_Description" : "Keep user data in sync with server on login (eg: name, email).",
"LDAP_Sync_User_Data_FieldMap" : "User Data Field Map",
"LDAP_Sync_User_Data_FieldMap_Description" : "Configure how user account fields (like email) are populated from a record in LDAP (once found). As an example, {\"cn\":\"name\", \"mail\":\"email\"} will choose a person's human readable name from the cn attribute, and their email from the mail attribute. Available fields include name, and email.",
"LDAP_TLS" : "TLS",
"LDAP_Url" : "LDAP URL",
"LDAP_Url_Description" : "URL of the LDAP server; example: ldap://company.dns.com",
"LDAP_Sync_User_Data_FieldMap_Description" : "Configure how user account fields (like email) are populated from a record in LDAP (once found). <br/>As an example, `{\"cn\":\"name\", \"mail\":\"email\"}` will choose a person's human readable name from the cn attribute, and their email from the mail attribute.<br/> Available fields include `name`, and `email`.",
"LDAP_Use_Custom_Domain_Search" : "Use Custom Domain Search",
"LDAP_Use_Custom_Domain_Search_Description" : "Write your own filter to search users in the LDAP server.",
"Leave_Group_Warning": "Are you sure you want to leave the group \"%s\"?",
"Leave_Private_Warning": "Are you sure you want to leave the discussion with \"%s\"?",
"Leave_room" : "Leave room",

@ -0,0 +1,45 @@
// Pass in username, password as normal
// customLdapOptions should be passed in if you want to override LDAP_DEFAULTS
// on any particular call (if you have multiple ldap servers you'd like to connect to)
// You'll likely want to set the dn value here {dn: "..."}
Meteor.loginWithLDAP = function(username, password, customLdapOptions, callback) {
// Retrieve arguments as array
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
// Pull username and password
username = args.shift();
password = args.shift();
// Check if last argument is a function
// if it is, pop it off and set callback to it
if (typeof args[args.length-1] == 'function') callback = args.pop(); else callback = null;
// if args still holds options item, grab it
if (args.length > 0) customLdapOptions = args.shift(); else customLdapOptions = {};
// Set up loginRequest object
var loginRequest = {
username: username,
ldapPass: password,
ldapOptions: customLdapOptions
};
Accounts.callLoginMethod({
// Call login method with ldap = true
// This will hook into our login handler for ldap
methodArguments: [loginRequest],
userCallback: function(error, result) {
if (error) {
if (callback) {
callback(error);
}
} else {
if (callback) {
callback();
}
}
}
});
};

@ -0,0 +1,172 @@
var slug = function (text) {
text = slugify(text, '.');
return text.replace(/[^0-9a-z-_.]/g, '');
};
function fallbackDefaultAccountSystem(bind, username, password) {
if (typeof username === 'string')
if (username.indexOf('@') === -1)
username = {username: username};
else
username = {email: username};
loginRequest = {
user: username,
password: {
digest: SHA256(password),
algorithm: "sha-256"
}
};
return Accounts._runLoginHandlers(bind, loginRequest);
}
function getDataToSyncUserData(ldapUser) {
const syncUserData = RocketChat.settings.get('LDAP_Sync_User_Data');
const syncUserDataFieldMap = RocketChat.settings.get('LDAP_Sync_User_Data_FieldMap').trim();
if (syncUserData && syncUserDataFieldMap) {
const fieldMap = JSON.parse(syncUserDataFieldMap);
let userData = {};
let emailList = [];
_.map(fieldMap, function(userField, ldapField) {
if (!ldapUser.hasOwnProperty(ldapField)) {
return;
}
switch (userField) {
case 'email':
if (_.isObject(ldapUser[ldapField] === 'object')) {
_.map(ldapUser[ldapField], function (item) {
emailList.push({ address: item, verified: true });
});
} else {
emailList.push({ address: ldapUser[ldapField], verified: true });
}
break;
case 'name':
userData.name = ldapUser[ldapField];
break;
}
});
if (emailList.length > 0) {
userData.emails = emailList;
}
if (_.size(userData)) {
return userData;
}
}
}
function syncUserData(userId, ldapUser) {
const userData = getDataToSyncUserData(ldapUser);
if (userId && userData) {
Meteor.users.update(userId, { $set: userData });
}
}
Accounts.registerLoginHandler("ldap", function(loginRequest) {
const self = this;
if (!loginRequest.ldapOptions) {
return undefined;
}
if (RocketChat.settings.get('LDAP_Enable') !== true) {
return fallbackDefaultAccountSystem(self, loginRequest.username, loginRequest.ldapPass);
}
const ldap = new LDAP();
let ldapUser;
try {
ldap.connectSync();
users = ldap.searchUsersSync(loginRequest.username);
if (users.length !== 1) {
console.log('LDAP: Search returned', users.length, 'record(s)');
throw new Error('User not Found');
}
if (ldap.authSync(users[0].dn, loginRequest.ldapPass) === true) {
ldapUser = users[0];
} else {
console.log('wrong password');
}
} catch(error) {
console.log(error);
}
ldap.disconnect();
if (ldapUser === undefined) {
console.log('[LDAP] Falling back to standard account base');
return fallbackDefaultAccountSystem(self, loginRequest.username, loginRequest.ldapPass);
}
const username = slug(loginRequest.username);
// Look to see if user already exists
const user = Meteor.users.findOne({
username: username
});
// Login user if they exist
if (user) {
if (user.ldap !== true) {
throw new Meteor.Error("LDAP-login-error", "LDAP Authentication succeded, but there's already an existing user with provided username ["+username+"] in Mongo.");
}
const stampedToken = Accounts._generateStampedLoginToken();
const hashStampedToken =
Meteor.users.update(user._id, {
$push: {
'services.resume.loginTokens': Accounts._hashStampedToken(stampedToken)
}
});
syncUserData(user._id, ldapUser);
return {
userId: user._id,
token: stampedToken.token
};
}
// Create new user
var userObject = {
username: username
};
let userData = getDataToSyncUserData(ldapUser);
if (userData && userData.emails) {
userObject.email = userData.emails[0].address;
} else if (ldapUser.mail && ldapUser.mail.indexOf('@') > -1) {
userObject.email = ldapUser.mail;
} else if (RocketChat.settings.get('LDAP_Default_Domain') !== '') {
userObject.email = username + '@' + RocketChat.settings.get('LDAP_Default_Domain');
} else {
throw new Meteor.Error("LDAP-login-error", "LDAP Authentication succeded, there is no email to create an account.");
}
let userId = Accounts.createUser(userObject);
syncUserData(userId, ldapUser);
Meteor.users.update(userId, {
$set: {
ldap: true
}
});
Meteor.runAsUser(userId, function() {
Meteor.call('joinDefaultChannels');
});
return {
userId: userId
};
});

@ -0,0 +1,38 @@
Meteor.startup ->
RocketChat.settings.addGroup 'LDAP', ->
enableQuery = {_id: 'LDAP_Enable', value: true}
enableTLSQuery = [
{_id: 'LDAP_Enable', value: true}
{_id: 'LDAP_Encryption', value: {$in: ['tls', 'ssl']}}
]
customBindSearchEnabledQuery = [
{_id: 'LDAP_Enable', value: true}
{_id: 'LDAP_Use_Custom_Domain_Search', value: true}
]
customBindSearchDisabledQuery = [
{_id: 'LDAP_Enable', value: true}
{_id: 'LDAP_Use_Custom_Domain_Search', value: false}
]
syncDataQuery = [
{_id: 'LDAP_Enable', value: true}
{_id: 'LDAP_Sync_User_Data', value: true}
]
@add 'LDAP_Enable', false, { type: 'boolean', public: true }
@add 'LDAP_Host', '', { type: 'string', enableQuery: enableQuery }
@add 'LDAP_Port', '389', { type: 'string', enableQuery: enableQuery }
@add 'LDAP_Encryption', 'plain', { type: 'select', values: [ { key: 'plain', i18nLabel: 'No_Encryption' }, { key: 'tls', i18nLabel: 'StartTLS' }, { key: 'ssl', i18nLabel: 'SSL/LDAPS' } ], enableQuery: enableQuery }
@add 'LDAP_CA_Cert', '', { type: 'string', multiline: true, enableQuery: enableTLSQuery }
@add 'LDAP_Reject_Unauthorized', true, { type: 'boolean', enableQuery: enableTLSQuery }
@add 'LDAP_Domain_Base', '', { type: 'string', enableQuery: enableQuery }
@add 'LDAP_Use_Custom_Domain_Search', false, { type: 'boolean' , enableQuery: enableQuery }
@add 'LDAP_Custom_Domain_Search', '', { type: 'string' , enableQuery: customBindSearchEnabledQuery }
@add 'LDAP_Domain_Search_User', '', { type: 'string', enableQuery: customBindSearchDisabledQuery }
@add 'LDAP_Domain_Search_Password', '', { type: 'string', enableQuery: customBindSearchDisabledQuery }
@add 'LDAP_Restricted_User_Groups', '', { type: 'string', enableQuery: customBindSearchDisabledQuery }
@add 'LDAP_Domain_Search_User_ID', 'sAMAccountName', { type: 'string', enableQuery: customBindSearchDisabledQuery }
@add 'LDAP_Domain_Search_Object_Class', 'user', { type: 'string', enableQuery: customBindSearchDisabledQuery }
@add 'LDAP_Domain_Search_Object_Category', 'person', { type: 'string', enableQuery: customBindSearchDisabledQuery }
@add 'LDAP_Sync_User_Data', false, { type: 'boolean' , enableQuery: enableQuery }
@add 'LDAP_Sync_User_Data_FieldMap', '{"cn":"name", "mail":"email"}', { type: 'string', enableQuery: syncDataQuery }
@add 'LDAP_Default_Domain', '', { type: 'string' , enableQuery: enableQuery }
Loading…
Cancel
Save