Add mysql database stuff
[mspang/pyceo.git] / ceo / members.py
index 5b85a4b..5ebf272 100644 (file)
@@ -9,7 +9,7 @@ Transactions are used in each method that modifies the database.
 Future changes to the members database that need to be atomic
 must also be moved into this module.
 """
-import os, re, subprocess, ldap
+import os, re, subprocess, ldap, socket
 from ceo import conf, ldapi, terms, remote, ceo_pb2
 from ceo.excep import InvalidArgument
 
@@ -91,6 +91,11 @@ def connect(auth_callback):
             if password == None:
                 raise e
 
+def connect_anonymous():
+    """Connect to LDAP."""
+
+    global ld
+    ld = ldap.initialize(cfg['ldap_server_url'])
 
 def disconnect():
     """Disconnect from LDAP."""
@@ -109,7 +114,7 @@ def connected():
 
 ### Members ###
 
-def create_member(username, password, name, program):
+def create_member(username, password, name, program, email):
     """
     Creates a UNIX user account with options tailored to CSC members.
 
@@ -118,6 +123,7 @@ def create_member(username, password, name, program):
         password - the desired UNIX password
         name     - the member's real name
         program  - the member's program of study
+       email    - email to place in .forward
 
     Exceptions:
         InvalidArgument - on bad account attributes provided
@@ -142,6 +148,7 @@ def create_member(username, password, name, program):
         request.password = password
         request.realname = name
         request.program = program
+       request.email = email
 
         out = remote.run_remote('adduser', request.SerializeToString())
 
@@ -162,6 +169,54 @@ def create_member(username, password, name, program):
         raise MemberException(e)
 
 
+def check_email(email):
+    match = re.match('^\S+?@(\S+)$', email)
+    if not match:
+        return 'Invalid email address'
+
+    # some characters are treated specially in .forward
+    for c in email:
+        if c in ('"', "'", ',', '|', '$', '/', '#', ':'):
+            return 'Invalid character in address: %s' % c
+
+    host = match.group(1)
+    try:
+        ip = socket.gethostbyname(host)
+    except:
+        return 'Invalid host: %s' % host
+
+
+def current_email(username):
+    fwdpath = '%s/%s/.forward' % (cfg['member_home'], username)
+    try:
+        fwd = open(fwdpath).read().strip()
+        if not check_email(fwd):
+            return fwd
+    except OSError:
+        pass
+    except IOError:
+        pass
+
+
+def change_email(username, forward):
+    try:
+        request = ceo_pb2.UpdateMail()
+        request.username = username
+        request.forward = forward
+
+        out = remote.run_remote('mail', request.SerializeToString())
+
+        response = ceo_pb2.AddUserResponse()
+        response.ParseFromString(out)
+
+        if any(message.status != 0 for message in response.messages):
+            return '\n'.join(message.message for message in response.messages)
+    except remote.RemoteException, e:
+        raise MemberException(e)
+    except OSError, e:
+        raise MemberException(e)
+
+
 def get(userid):
     """
     Look up attributes of a member by userid.
@@ -391,6 +446,7 @@ def create_club(username, name):
         request.type = ceo_pb2.AddUser.CLUB
         request.username = username
         request.realname = name
+
         out = remote.run_remote('adduser', request.SerializeToString())
 
         response = ceo_pb2.AddUserResponse()