JackAdams / meteor-accounts-ldap

Authentication against an LDAP server in Meteor
MIT License
21 stars 12 forks source link

thumbnailPhoto stored as string #24

Closed sandrich closed 6 years ago

sandrich commented 6 years ago

Hi

I want to display the thumbnailPhoto that is delivered through AD. The problem is that ldapjs is returning it as string. there is a solution to this issue

https://github.com/joyent/node-ldapjs/issues/137#issuecomment-22525683

How could this be implemented in your module?

JackAdams commented 6 years ago

I don't have a full grasp of what's going on in the code referenced above but, if you can get this working, I'd be wide open to accepting a PR.

sandrich commented 6 years ago

I modified the ldap_server.js and added

function getProperObject(entry) {
  var obj = {
    dn: entry.dn.toString(),
    controls: []
  };
  entry.attributes.forEach(function (a) {
    var buf = a.buffers;
    var val = a.vals;
    var item;
    if ( a.type == 'thumbnailPhoto' )
      item = buf;
    else
      item = val;
    if (item && item.length) {
      if (item.length > 1) {
        obj[a.type] = item.slice();
      } else {
        obj[a.type] = item[0];
      }
    } else {
      obj[a.type] = [];
    }
  });
  entry.controls.forEach(function (element, index, array) {
    obj.controls.push(element.json);
  });
  return obj;
}

Then in the LDAP._search function I modified

res.on('searchEntry', function (entry) {
          var ob = getProperObject(entry);

          var person = entry.object;
          var usernameOrEmail = searchUsername.toLowerCase();
          var username = (isEmail) ? usernameOrEmail.split('@')[0] : usernameOrEmail; // Used to have: person.cn || usernameOrEmail.split('@')[0] -- guessing the username based on the email is pretty poor
          var email = username + '@' + LDAP._serverDnToFQDN(serverDn); // (isEmail) ? usernameOrEmail : person.mail ||
          userObj = {
            username: username,
            email: (isEmail) ? usernameOrEmail : person.mail || email, // best we can do with the info we have
            password: request.password,
            profile: _.pick(entry.object, _.without(settings.whiteListedFields, 'mail'))
          };

          userObj.profile.thumbnailPhoto = ob.thumbnailPhoto

          // _.extend({username: username, email : [{address: email, verified: LDAP.autoVerifyEmail}]}, _.pick(entry.object, _.without(settings.whiteListedFields, 'mail')));
          searchFuture.return({userObj: userObj, person: person, ldapIdentifierUsername: username});
        });

I am sure this could be implemented a bit better. That is why I have no PR yet. Any suggestion?

JackAdams commented 6 years ago

Does this work as intended? My suggestion would be to make sure that it only gets added to the userObj if it is one of the whitelisted fields. As it currently stands, it looks like the thumbnail gets returned for every search.