Browse Source

- Add LDAP. In progress.

Thanks to maximest-pierre, Akuket and xet.

Related #119
Lauri Ojansivu 6 years ago
parent
commit
288800eafc

+ 1 - 0
.meteor/packages

@@ -87,4 +87,5 @@ momentjs:moment@2.22.2
 browser-policy-framing
 mquandalle:moment
 msavin:usercache
+wekan:wekan-ldap
 wekan:accounts-cas

+ 2 - 0
.meteor/versions

@@ -179,5 +179,7 @@ useraccounts:unstyled@1.14.2
 verron:autosize@3.0.8
 webapp@1.4.0
 webapp-hashing@1.0.9
+wekan:wekan-ldap@0.0.2
+yasaricli:slugify@0.0.7
 wekan:accounts-cas@0.1.0
 zimme:active-route@2.3.2

+ 1 - 0
client/components/main/layouts.jade

@@ -18,6 +18,7 @@ template(name="userFormsLayout")
       img(src="{{pathFor '/wekan-logo.png'}}" alt="Wekan")
     section.auth-dialog
       +Template.dynamic(template=content)
+      +connectionMethod
       if isCas
         .at-form
           button#cas(class='at-btn submit' type='submit') {{casSignInLabel}}

+ 40 - 1
client/components/main/layouts.js

@@ -39,7 +39,7 @@ Template.userFormsLayout.helpers({
     const curLang = T9n.getLanguage() || 'en';
     return t9nTag === curLang;
   },
-
+/*
   isCas() {
     return Meteor.settings.public &&
       Meteor.settings.public.cas &&
@@ -49,6 +49,7 @@ Template.userFormsLayout.helpers({
   casSignInLabel() {
     return TAPi18n.__('casSignIn', {}, T9n.getLanguage() || 'en');
   },
+*/
 });
 
 Template.userFormsLayout.events({
@@ -64,6 +65,44 @@ Template.userFormsLayout.events({
       }
     });
   },
+  'submit form'(event) {
+    const connectionMethod = $('.select-connection').val();
+
+    // Local account
+    if (connectionMethod === 'default') {
+      return;
+    }
+
+    // TODO : find a way to block "submit #at-pwd-form" of the at_pwd_form.js
+
+    const inputs = event.target.getElementsByTagName('input');
+
+    const email = inputs.namedItem('at-field-username_and_email').value;
+    const password = inputs.namedItem('at-field-password').value;
+
+    // Ldap account
+    if (connectionMethod === 'ldap') {
+      // Check if the user can use the ldap connection
+      Meteor.subscribe('user-connection-method', email, {
+        onReady() {
+          const ldap = Users.findOne();
+
+          if (ldap) {
+            // Use the ldap connection package
+            Meteor.loginWithLDAP(email, password, function(error) {
+              if (!error) {
+                // Connection
+                return FlowRouter.go('/');
+              } else {
+                return error;
+              }
+            });
+          }
+          return this.stop();
+        },
+      });
+    }
+  },
 });
 
 Template.defaultLayout.events({

+ 6 - 0
client/components/settings/connectionMethod.jade

@@ -0,0 +1,6 @@
+template(name='connectionMethod')
+  div.at-form-connection
+    label Authentication method
+    select.select-connection
+        each connections
+            option(value="{{value}}") {{_ value}}

+ 34 - 0
client/components/settings/connectionMethod.js

@@ -0,0 +1,34 @@
+Template.connectionMethod.onCreated(function() {
+  this.connectionMethods = new ReactiveVar([]);
+
+  Meteor.call('getConnectionsEnabled', (_, result) => {
+    if (result) {
+      // TODO : add a management of different languages
+      // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
+      this.connectionMethods.set([
+        {value: 'default'},
+        // Gets only the connection methods availables
+        ...Object.entries(result).filter((e) => e[1]).map((e) => ({value: e[0]})),
+      ]);
+    }
+
+    // If only the default authentication available, hides the select boxe
+    const content = $('.at-form-connection');
+    if (!(this.connectionMethods.get().length > 1)) {
+      content.hide();
+    } else {
+      content.show();
+    }
+  });
+});
+
+Template.connectionMethod.onRendered(() => {
+  // Moves the select boxe in the first place of the at-pwd-form div
+  $('.at-form-connection').detach().prependTo('.at-pwd-form');
+});
+
+Template.connectionMethod.helpers({
+  connections() {
+    return Template.instance().connectionMethods.get();
+  },
+});

+ 33 - 0
models/settings.js

@@ -128,6 +128,18 @@ if (Meteor.isServer) {
     }
   }
 
+  function isLdapEnabled() {
+    return process.env.LDAP_ENABLE === 'true';
+  }
+
+  function isOauth2Enabled() {
+    return process.env.OAUTH2_ENABLED === 'true';
+  }
+
+  function isCasEnabled() {
+    return process.env.CAS_ENABLED === 'true';
+  }
+
   Meteor.methods({
     sendInvitation(emails, boards) {
       check(emails, [String]);
@@ -197,5 +209,26 @@ if (Meteor.isServer) {
         withUserName: process.env.MATOMO_WITH_USERNAME || false,
       };
     },
+
+    _isLdapEnabled() {
+      return isLdapEnabled();
+    },
+
+    _isOauth2Enabled() {
+      return isOauth2Enabled();
+    },
+
+    _isCasEnabled() {
+      return isCasEnabled();
+    },
+
+    // Gets all connection methods to use it in the Template
+    getConnectionsEnabled() {
+      return {
+        ldap: isLdapEnabled(),
+        oauth2: isOauth2Enabled(),
+        cas: isCasEnabled(),
+      };
+    },
   });
 }

+ 12 - 3
models/users.js

@@ -127,6 +127,11 @@ Users.attachSchema(new SimpleSchema({
     type: Boolean,
     optional: true,
   },
+  // TODO : write a migration and check if using a ldap parameter is better than a connection_type parameter
+  ldap: {
+    type: Boolean,
+    optional: true,
+  },
 }));
 
 Users.allow({
@@ -490,7 +495,6 @@ if (Meteor.isServer) {
 
     if (user.services.oidc) {
       const email = user.services.oidc.email.toLowerCase();
-
       user.username = user.services.oidc.username;
       user.emails = [{ address: email, verified: true }];
       const initials = user.services.oidc.fullname.match(/\b[a-zA-Z]/g).join('').toUpperCase();
@@ -518,7 +522,10 @@ if (Meteor.isServer) {
     }
 
     const disableRegistration = Settings.findOne().disableRegistration;
-    if (!disableRegistration) {
+    // If ldap, bypass the inviation code if the self registration isn't allowed.
+    // TODO : pay attention if ldap field in the user model change to another content ex : ldap field to connection_type
+    if (options.ldap || !disableRegistration) {
+      user.ldap = true;
       return user;
     }
 
@@ -636,7 +643,9 @@ if (Meteor.isServer) {
 
     //invite user to corresponding boards
     const disableRegistration = Settings.findOne().disableRegistration;
-    if (disableRegistration) {
+    // If ldap, bypass the inviation code if the self registration isn't allowed.
+    // TODO : pay attention if ldap field in the user model change to another content ex : ldap field to connection_type
+    if (!doc.ldap && disableRegistration) {
       const invitationCode = InvitationCodes.findOne({code: doc.profile.icode, valid: true});
       if (!invitationCode) {
         throw new Meteor.Error('error-invitation-code-not-exist');

+ 10 - 0
server/publications/users.js

@@ -17,3 +17,13 @@ Meteor.publish('user-admin', function() {
     },
   });
 });
+
+Meteor.publish('user-connection-method', function(match) {
+  check(match, String);
+
+  return Users.find({$or: [{email: match}, {username: match}]}, {
+    fields: {
+      ldap: 1,
+    },
+  });
+});