Switch to side-by-side view

--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1,8 +1,10 @@
 '''
 Allura plugins for authentication and project registration
 '''
+import re
+import os
 import logging
-import re
+import subprocess
 
 from random import randint
 from hashlib import sha256
@@ -10,6 +12,7 @@
 from datetime import datetime
 
 import ldap
+from ldap import modlist
 import pkg_resources
 from tg import config
 from pylons import g, c
@@ -80,6 +83,9 @@
     def set_password(self, user, old_password, new_password):
         raise NotImplementedError, 'set_password'
 
+    def upload_sshkey(self, username, pubkey):
+        raise NotImplemented, 'upload_sshkey'
+
 class LocalAuthenticationProvider(AuthenticationProvider):
 
     def register_user(self, user_doc):
@@ -123,43 +129,66 @@
 
     def register_user(self, user_doc):
         from allura import model as M
-        password = user_doc.pop('password', None)
+        password = user_doc['password'].encode('utf-8')
         result = M.User(**user_doc)
-        dn = 'uid=%s,%s' % (user_doc['username'], config['auth.ldap.suffix'])
+        dn_u = 'uid=%s,%s' % (user_doc['username'], config['auth.ldap.suffix'])
+        uid = str(M.AuthGlobals.get_next_uid())
         try:
             con = ldap.initialize(config['auth.ldap.server'])
             con.bind_s(config['auth.ldap.admin_dn'],
                        config['auth.ldap.admin_password'])
-            ldap_info = dict(
-                uid=user_doc['username'],
-                displayName=user_doc['display_name'],
-                cn=user_doc['display_name'],
+            uname = user_doc['username'].encode('utf-8')
+            display_name = user_doc['display_name'].encode('utf-8')
+            ldif_u = modlist.addModlist(dict(
+                uid=uname,
                 userPassword=password,
-                objectClass=['inetOrgPerson'],
-                givenName=user_doc['display_name'].split()[0],
-                sn=user_doc['display_name'].split()[-1])
-            ldap_info = dict((k,v) for k,v in ldap_info.iteritems()
-                             if v is not None)
+                objectClass=['account', 'posixAccount' ],
+                cn=display_name,
+                uidNumber=uid,
+                gidNumber='10001',
+                homeDirectory='/home/' + uname,
+                loginShell='/bin/bash',
+                gecos=uname,
+                description='SCM user account'))
             try:
-                con.add_s(dn, ldap_info.items())
+                con.add_s(dn_u, ldif_u)
             except ldap.ALREADY_EXISTS:
-                con.modify_s(dn, [(ldap.MOD_REPLACE, k, v)
-                                  for k,v in ldap_info.iteritems()])
+                log.exception('Trying to create existing user %s', uname)
+                raise
             con.unbind_s()
+            argv = ('schroot -d / -c %s -u root /ldap-userconfig.py init %s' % (
+                config['auth.ldap.schroot_name'], user_doc['username'])).split()
+            p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+            rc = p.wait()
+            if rc != 0:
+                log.error('Error creating home directory for %s',
+                          user_doc['username'])
         except:
             raise
         return result
 
+    def upload_sshkey(self, username, pubkey):
+            argv = ('schroot -d / -c %s -u root /ldap-userconfig.py upload %s' % (
+                config['auth.ldap.schroot_name'], username)).split() + [ pubkey ]
+            p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+            rc = p.wait()
+            if rc != 0:
+                errmsg = p.stdout.read()
+                log.exception('Error uploading public SSH key for %s: %s',
+                              username, errmsg)
+                assert False, errmsg
+
     def by_username(self, username):
         from allura import model as M
         return M.User.query.get(username=username)
 
     def set_password(self, user, old_password, new_password):
         try:
-            dn = 'uid=%s,%s' % (self.username, config['auth.ldap.suffix'])
+            import pdb; pdb.set_trace()
+            dn = 'uid=%s,%s' % (user.username, config['auth.ldap.suffix'])
             con = ldap.initialize(config['auth.ldap.server'])
-            con.bind_s(dn, old_password)
-            con.modify_s(dn, [(ldap.MOD_REPLACE, 'userPassword', new_password)])
+            con.bind_s(dn, old_password.encode('utf-8'))
+            con.modify_s(dn, [(ldap.MOD_REPLACE, 'userPassword', new_password.encode('utf-8'))])
             con.unbind_s()
         except ldap.INVALID_CREDENTIALS:
             raise exc.HTTPUnauthorized()
@@ -301,6 +330,16 @@
         }
     }
 
+    @LazyProperty
+    def password_change_form(self):
+        from allura.lib.widgets.forms import PasswordChangeForm
+        return PasswordChangeForm(action='/auth/prefs/change_password')
+
+    @LazyProperty
+    def upload_key_form(self):
+        from allura.lib.widgets.forms import UploadKeyForm
+        return UploadKeyForm(action='/auth/prefs/upload_sshkey')
+
     @property
     def master(self):
         return self.master_template
@@ -328,6 +367,5 @@
         else:
             return app.icon_url(size)
 
-
 class LocalProjectRegistrationProvider(ProjectRegistrationProvider):
     pass