forked from public/pyceo
Rip out studentid support
This commit is contained in:
parent
394784afde
commit
299c25d610
|
@ -25,7 +25,7 @@ cfg = {}
|
|||
def load_configuration():
|
||||
"""Load Members Configuration"""
|
||||
|
||||
string_fields = [ 'studentid_regex', 'realname_regex', 'server',
|
||||
string_fields = [ 'realname_regex', 'server',
|
||||
'database', 'user', 'password', 'server_url', 'users_base',
|
||||
'groups_base', 'admin_bind_dn', 'admin_bind_pw' ]
|
||||
|
||||
|
@ -47,20 +47,6 @@ ConfigurationException = conf.ConfigurationException
|
|||
class MemberException(Exception):
|
||||
"""Base exception class for member-related errors."""
|
||||
|
||||
class DuplicateStudentID(MemberException):
|
||||
"""Exception class for student ID conflicts."""
|
||||
def __init__(self, studentid):
|
||||
self.studentid = studentid
|
||||
def __str__(self):
|
||||
return "Student ID already exists in the database: %s" % self.studentid
|
||||
|
||||
class InvalidStudentID(MemberException):
|
||||
"""Exception class for malformed student IDs."""
|
||||
def __init__(self, studentid):
|
||||
self.studentid = studentid
|
||||
def __str__(self):
|
||||
return "Student ID is invalid: %s" % self.studentid
|
||||
|
||||
class InvalidTerm(MemberException):
|
||||
"""Exception class for malformed terms."""
|
||||
def __init__(self, term):
|
||||
|
@ -111,7 +97,7 @@ def connected():
|
|||
|
||||
### Member Table ###
|
||||
|
||||
def new(uid, realname, studentid=None, program=None):
|
||||
def new(uid, realname, program=None):
|
||||
"""
|
||||
Registers a new CSC member. The member is added to the members table
|
||||
and registered for the current term.
|
||||
|
@ -119,44 +105,32 @@ def new(uid, realname, studentid=None, program=None):
|
|||
Parameters:
|
||||
uid - the initial user id
|
||||
realname - the full real name of the member
|
||||
studentid - the student id number of the member
|
||||
program - the program of study of the member
|
||||
|
||||
Returns: the username of the new member
|
||||
|
||||
Exceptions:
|
||||
DuplicateStudentID - if the student id already exists in the database
|
||||
InvalidStudentID - if the student id is malformed
|
||||
InvalidRealName - if the real name is malformed
|
||||
|
||||
Example: new("Michael Spang", program="CS") -> "mspang"
|
||||
"""
|
||||
|
||||
# blank attributes should be NULL
|
||||
if studentid == '': studentid = None
|
||||
if program == '': program = None
|
||||
if uid == '': uid = None
|
||||
|
||||
# check the student id format
|
||||
if studentid is not None and not re.match(cfg['studentid_regex'], str(studentid)):
|
||||
raise InvalidStudentID(studentid)
|
||||
|
||||
# check real name format (UNIX account real names must not contain [,:=])
|
||||
if not re.match(cfg['realname_regex'], realname):
|
||||
raise InvalidRealName(realname)
|
||||
|
||||
# check for duplicate student id
|
||||
member = ldap_connection.member_search_studentid(studentid)
|
||||
if member:
|
||||
raise DuplicateStudentID(studentid)
|
||||
|
||||
# check for duplicate userid
|
||||
member = ldap_connection.user_lookup(uid)
|
||||
if member:
|
||||
raise InvalidArgument("uid", uid, "duplicate uid")
|
||||
|
||||
# add the member to the directory
|
||||
ldap_connection.member_add(uid, realname, studentid, program)
|
||||
ldap_connection.member_add(uid, realname, program)
|
||||
|
||||
# register them for this term in the directory
|
||||
member = ldap_connection.member_lookup(uid)
|
||||
|
@ -182,27 +156,6 @@ def get(userid):
|
|||
return ldap_connection.user_lookup(userid)
|
||||
|
||||
|
||||
def get_studentid(studentid):
|
||||
"""
|
||||
Look up attributes of a member by studentid.
|
||||
|
||||
Parameters:
|
||||
studentid - the student ID number
|
||||
|
||||
Returns: a dict of members
|
||||
|
||||
Example: get(...) -> {
|
||||
'mspang': {
|
||||
'name': [ 'Michael Spang' ],
|
||||
'program': [ 'Computer Science' ],
|
||||
}
|
||||
...
|
||||
}
|
||||
"""
|
||||
|
||||
return ldap_connection.member_search_studentid(studentid)
|
||||
|
||||
|
||||
def list_term(term):
|
||||
"""
|
||||
Build a list of members in a term.
|
||||
|
@ -354,21 +307,18 @@ if __name__ == '__main__':
|
|||
|
||||
from csc.common.test import *
|
||||
|
||||
# t=test m=member s=student u=updated
|
||||
# t=test m=member u=updated
|
||||
tmname = 'Test Member'
|
||||
tmuid = 'testmember'
|
||||
tmprogram = 'Metaphysics'
|
||||
tmsid = '00000000'
|
||||
tm2name = 'Test Member 2'
|
||||
tm2uid = 'testmember2'
|
||||
tm2sid = '00000001'
|
||||
tm2uname = 'Test Member II'
|
||||
tm2usid = '00000002'
|
||||
tm2uprogram = 'Pseudoscience'
|
||||
|
||||
tmdict = {'cn': [tmname], 'uid': [tmuid], 'program': [tmprogram], 'studentid': [tmsid] }
|
||||
tm2dict = {'cn': [tm2name], 'uid': [tm2uid], 'studentid': [tm2sid] }
|
||||
tm2udict = {'cn': [tm2uname], 'uid': [tm2uid], 'program': [tm2uprogram], 'studentid': [tm2usid] }
|
||||
tmdict = {'cn': [tmname], 'uid': [tmuid], 'program': [tmprogram] }
|
||||
tm2dict = {'cn': [tm2name], 'uid': [tm2uid] }
|
||||
tm2udict = {'cn': [tm2uname], 'uid': [tm2uid], 'program': [tm2uprogram] }
|
||||
|
||||
thisterm = terms.current()
|
||||
nextterm = terms.next(thisterm)
|
||||
|
@ -381,16 +331,9 @@ if __name__ == '__main__':
|
|||
assert_equal(True, connected())
|
||||
success()
|
||||
|
||||
dmid = get_studentid(tmsid)
|
||||
if tmuid in dmid: delete(dmid[tmuid]['uid'][0])
|
||||
dmid = get_studentid(tm2sid)
|
||||
if tm2uid in dmid: delete(dmid[tm2uid]['uid'][0])
|
||||
dmid = get_studentid(tm2usid)
|
||||
if tm2uid in dmid: delete(dmid[tm2uid]['uid'][0])
|
||||
|
||||
test(new)
|
||||
tmid = new(tmuid, tmname, tmsid, tmprogram)
|
||||
tm2id = new(tm2uid, tm2name, tm2sid)
|
||||
tmid = new(tmuid, tmname, tmprogram)
|
||||
tm2id = new(tm2uid, tm2name)
|
||||
success()
|
||||
|
||||
test(registered)
|
||||
|
@ -439,17 +382,6 @@ if __name__ == '__main__':
|
|||
assert_equal(tm2dict, tmp)
|
||||
success()
|
||||
|
||||
test(get_studentid)
|
||||
tmp = get_studentid(tm2sid)[tm2uid]
|
||||
del tmp['objectClass']
|
||||
del tmp['term']
|
||||
assert_equal(tm2dict, tmp)
|
||||
tmp = get_studentid(tmsid)[tmuid]
|
||||
del tmp['objectClass']
|
||||
del tmp['term']
|
||||
assert_equal(tmdict, tmp)
|
||||
success()
|
||||
|
||||
test(delete)
|
||||
delete(tmid)
|
||||
delete(tm2id)
|
||||
|
|
|
@ -52,7 +52,7 @@ def action_library(wnd):
|
|||
def action_new_member(wnd):
|
||||
"""Interactively add a new member."""
|
||||
|
||||
userid, studentid, program = '', None, ''
|
||||
userid, program = '', ''
|
||||
|
||||
msgbox(wnd, "Membership is $2.00 CDN. Please ensure\n"
|
||||
"the money is desposited in the safe\n"
|
||||
|
@ -66,18 +66,6 @@ def action_new_member(wnd):
|
|||
if not realname or realname.lower() == 'exit':
|
||||
return False
|
||||
|
||||
# read the student id
|
||||
prompt = "New member's student ID:"
|
||||
while studentid is None or (re.search("[^0-9]", studentid) and not studentid.lower() == 'exit'):
|
||||
studentid = inputbox(wnd, prompt, 30)
|
||||
|
||||
# abort if exit is entered
|
||||
if studentid.lower() == 'exit':
|
||||
return False
|
||||
|
||||
if studentid == '':
|
||||
studentid = None
|
||||
|
||||
# read the program of study
|
||||
prompt = "New member's program of study:"
|
||||
program = inputbox(wnd, prompt, 30)
|
||||
|
@ -100,17 +88,11 @@ def action_new_member(wnd):
|
|||
|
||||
# attempt to create the member
|
||||
try:
|
||||
members.new(userid, realname, studentid, program)
|
||||
members.new(userid, realname, program)
|
||||
|
||||
msgbox(wnd, "Success! Your username is %s. You are now registered\n"
|
||||
% userid + "for the " + terms.current() + " term.")
|
||||
|
||||
except members.InvalidStudentID:
|
||||
msgbox(wnd, "Invalid student ID: %s" % studentid)
|
||||
return False
|
||||
except members.DuplicateStudentID:
|
||||
msgbox(wnd, "A member with this student ID exists.")
|
||||
return False
|
||||
except members.InvalidRealName:
|
||||
msgbox(wnd, 'Invalid real name: "%s"' % realname)
|
||||
return False
|
||||
|
@ -328,7 +310,7 @@ def display_member_details(wnd, member):
|
|||
term_list.sort( terms.compare )
|
||||
|
||||
# labels for data
|
||||
id_label, studentid_label, name_label = "ID:", "StudentID:", "Name:"
|
||||
id_label, name_label = "ID:", "Name:"
|
||||
program_label, terms_label = "Program:", "Terms:"
|
||||
|
||||
if 'program' in member:
|
||||
|
@ -336,14 +318,9 @@ def display_member_details(wnd, member):
|
|||
else:
|
||||
program = None
|
||||
|
||||
if 'studentid' in member:
|
||||
studentid = member['studentid'][0]
|
||||
else:
|
||||
studentid = None
|
||||
|
||||
# format it all into a massive string
|
||||
message = "%8s %-20s %10s %-10s\n" % (name_label, member['cn'][0], id_label, member['uid'][0]) + \
|
||||
"%8s %-20s %10s %-10s\n" % (program_label, program, studentid_label, studentid)
|
||||
"%8s %-20s\n" % (program_label, program )
|
||||
|
||||
message += "%s %s" % (terms_label, " ".join(term_list))
|
||||
|
||||
|
@ -390,13 +367,8 @@ def format_members(member_list):
|
|||
program = member['program'][0]
|
||||
else:
|
||||
program = None
|
||||
if 'studentid' in member:
|
||||
studentid = member['studentid'][0]
|
||||
else:
|
||||
studentid = None
|
||||
attrs = ( uid, member['cn'][0],
|
||||
studentid, program )
|
||||
buf += "%10s %30s %10s\n%41s\n\n" % attrs
|
||||
attrs = ( uid, member['cn'][0], program )
|
||||
buf += "%10s %30s\n%41s\n\n" % attrs
|
||||
|
||||
return buf
|
||||
|
||||
|
@ -458,34 +430,6 @@ def action_list_name(wnd):
|
|||
return False
|
||||
|
||||
|
||||
def action_list_studentid(wnd):
|
||||
"""Interactively search for members by student id."""
|
||||
|
||||
studentid = None
|
||||
|
||||
# read the studentid
|
||||
prompt = "Enter the member's student id: "
|
||||
studentid = inputbox(wnd, prompt, 41)
|
||||
|
||||
# abort when exit is entered
|
||||
if not studentid or studentid.lower() == 'exit':
|
||||
return False
|
||||
|
||||
# connect the members module to its backends if necessary
|
||||
if not members.connected(): members.connect()
|
||||
|
||||
# retrieve a list of members for term
|
||||
member_list = members.get_studentid(studentid)
|
||||
|
||||
# format the data into a mess of text
|
||||
buf = format_members(member_list.values())
|
||||
|
||||
# display the mass of text with a pager
|
||||
page( buf )
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def null_callback(wnd):
|
||||
"""Callback for unimplemented menu options."""
|
||||
return False
|
||||
|
@ -504,7 +448,6 @@ top_menu = [
|
|||
( "Display a member", action_display_member ),
|
||||
( "List members registered in a term", action_list_term ),
|
||||
( "Search for a member by name", action_list_name ),
|
||||
( "Search for a member by student id", action_list_studentid ),
|
||||
( "Create an account", action_create_account ),
|
||||
( "Library functions", action_library ),
|
||||
( "Exit", exit_callback ),
|
||||
|
|
|
@ -494,17 +494,6 @@ class LDAPConnection(object):
|
|||
return self.lookup(dn, 'member')
|
||||
|
||||
|
||||
def member_search_studentid(self, studentid):
|
||||
"""
|
||||
Retrieves a list of members with a certain studentid.
|
||||
|
||||
Returns: a dictionary mapping uids to attributes
|
||||
"""
|
||||
|
||||
search_filter = '(&(objectClass=member)(studentid=%s))'
|
||||
return self.user_search(search_filter, [ studentid ] )
|
||||
|
||||
|
||||
def member_search_name(self, name):
|
||||
"""
|
||||
Retrieves a list of members with the specified name (fuzzy).
|
||||
|
@ -538,14 +527,13 @@ class LDAPConnection(object):
|
|||
return self.user_search(search_filter, [ program ])
|
||||
|
||||
|
||||
def member_add(self, uid, cn, studentid, program=None, description=None):
|
||||
def member_add(self, uid, cn, program=None, description=None):
|
||||
"""
|
||||
Adds a member to the directory.
|
||||
|
||||
Parameters:
|
||||
uid - the UNIX username for the member
|
||||
cn - the real name of the member
|
||||
studentid - the member's student ID number
|
||||
program - the member's program of study
|
||||
description - a description for the entry
|
||||
"""
|
||||
|
@ -555,7 +543,6 @@ class LDAPConnection(object):
|
|||
'objectClass': [ 'top', 'account', 'member' ],
|
||||
'uid': [ uid ],
|
||||
'cn': [ cn ],
|
||||
'studentid': [ studentid ],
|
||||
}
|
||||
|
||||
if program:
|
||||
|
@ -680,7 +667,6 @@ if __name__ == '__main__':
|
|||
tgname = 'testgroup'
|
||||
tmname = 'testmember'
|
||||
tmrname = 'Test Member'
|
||||
tmstudentid = '99999999'
|
||||
tmprogram = 'UBW'
|
||||
tmdesc = 'Test Description'
|
||||
cushell = '/bin/true'
|
||||
|
@ -747,13 +733,12 @@ if __name__ == '__main__':
|
|||
emdata = {
|
||||
'uid': [ tmname ],
|
||||
'cn': [ tmrname ],
|
||||
'studentid': [ tmstudentid ],
|
||||
'program': [ tmprogram ],
|
||||
'description': [ tmdesc ],
|
||||
}
|
||||
|
||||
test(LDAPConnection.member_add)
|
||||
connection.member_add(tmname, tmrname, tmstudentid, tmprogram, tmdesc)
|
||||
connection.member_add(tmname, tmrname, tmprogram, tmdesc)
|
||||
success()
|
||||
|
||||
tggid = unusedids.pop()
|
||||
|
@ -805,12 +790,6 @@ if __name__ == '__main__':
|
|||
fail("%s not in %s" % (tuname, ulist))
|
||||
success()
|
||||
|
||||
test(LDAPConnection.member_search_studentid)
|
||||
mlist = connection.member_search_studentid(tmstudentid).keys()
|
||||
emlist = [ tmname ]
|
||||
assert_equal(emlist, mlist)
|
||||
success()
|
||||
|
||||
test(LDAPConnection.member_search_name)
|
||||
mlist = connection.member_search_name(tmrname)
|
||||
if tmname not in mlist:
|
||||
|
|
Loading…
Reference in New Issue