|  |  |  | @ -50,24 +50,24 @@ def delete_password(name, length=10):@@ -50,24 +50,24 @@ def delete_password(name, length=10): | 
			
		
	
		
			
				
					|  |  |  |  |     # so redirect this to /dev/null | 
			
		
	
		
			
				
					|  |  |  |  |     with open(os.devnull, 'wb') as devnull: | 
			
		
	
		
			
				
					|  |  |  |  |         subprocess.check_call(["htpasswd", "-D", HTPWD_PATH, name], stderr=devnull) | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | # class definitions | 
			
		
	
		
			
				
					|  |  |  |  | class User(object): | 
			
		
	
		
			
				
					|  |  |  |  |     """ Collect the username, group and access control lists """ | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def __init__(self, name, group): | 
			
		
	
		
			
				
					|  |  |  |  |         """ initialization of the class """ | 
			
		
	
		
			
				
					|  |  |  |  |         self.name = name | 
			
		
	
		
			
				
					|  |  |  |  |         self.group = group | 
			
		
	
		
			
				
					|  |  |  |  |         self.write_acl = [] | 
			
		
	
		
			
				
					|  |  |  |  |         self.read_acl = [] | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def __str__(self): | 
			
		
	
		
			
				
					|  |  |  |  |         """ return a string representation """ | 
			
		
	
		
			
				
					|  |  |  |  |         return self.name | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def __repr__(self): | 
			
		
	
		
			
				
					|  |  |  |  |         """ return a string representation of the object """ | 
			
		
	
		
			
				
					|  |  |  |  |         return "<User '%s@%s'>" % (self.name, self.group) | 
			
		
	
	
		
			
				
					|  |  |  | @ -79,12 +79,17 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object):@@ -79,12 +79,17 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object): | 
			
		
	
		
			
				
					|  |  |  |  |     def __init__(self): | 
			
		
	
		
			
				
					|  |  |  |  |         """ initialization of the class """ | 
			
		
	
		
			
				
					|  |  |  |  |         self.users = None | 
			
		
	
		
			
				
					|  |  |  |  |         self._acl_defaults = { WRITE_ACL: [], READ_ACL: [] } | 
			
		
	
		
			
				
					|  |  |  |  |         super(AuthzConfigParser, self).__init__() | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def optionxform(self, value): | 
			
		
	
		
			
				
					|  |  |  |  |         """ reset the method to use cases ensitive names """ | 
			
		
	
		
			
				
					|  |  |  |  |         return str(value) | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def read(self, path): | 
			
		
	
		
			
				
					|  |  |  |  |         super(AuthzConfigParser, self).read(path) | 
			
		
	
		
			
				
					|  |  |  |  |         self._acl_defaults = self.get_folder_info("") | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def extract_users(self): | 
			
		
	
		
			
				
					|  |  |  |  |         """ extract user information from config """ | 
			
		
	
		
			
				
					|  |  |  |  |         users = dict() | 
			
		
	
	
		
			
				
					|  |  |  | @ -96,7 +101,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object):@@ -96,7 +101,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object): | 
			
		
	
		
			
				
					|  |  |  |  |                     raise Exception("Found duplicate entry for user " + username) | 
			
		
	
		
			
				
					|  |  |  |  |                 user = User(username, group) | 
			
		
	
		
			
				
					|  |  |  |  |                 users[username] = user | 
			
		
	
		
			
				
					|  |  |  |  |         # second we scan each section that is related to an svn folder (it  | 
			
		
	
		
			
				
					|  |  |  |  |         # second we scan each section that is related to an svn folder (it | 
			
		
	
		
			
				
					|  |  |  |  |         # starts with the svn base) for read and write access user entries | 
			
		
	
		
			
				
					|  |  |  |  |         for section in self.sections(): | 
			
		
	
		
			
				
					|  |  |  |  |             if section.startswith(SVN_BASE): | 
			
		
	
	
		
			
				
					|  |  |  | @ -116,12 +121,16 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object):@@ -116,12 +121,16 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object): | 
			
		
	
		
			
				
					|  |  |  |  |             name = SVN_BASE + name | 
			
		
	
		
			
				
					|  |  |  |  |         if not self.has_section(name): | 
			
		
	
		
			
				
					|  |  |  |  |             return None | 
			
		
	
		
			
				
					|  |  |  |  |         info = { WRITE_ACL: [], READ_ACL: [] } | 
			
		
	
		
			
				
					|  |  |  |  |         info = self._acl_defaults.copy() | 
			
		
	
		
			
				
					|  |  |  |  |         for (option, value) in self.items(name): | 
			
		
	
		
			
				
					|  |  |  |  |             if value in (WRITE_ACL, READ_ACL): | 
			
		
	
		
			
				
					|  |  |  |  |                 info[value].append(option) | 
			
		
	
		
			
				
					|  |  |  |  |             if not value: | 
			
		
	
		
			
				
					|  |  |  |  |                 for acltype in (WRITE_ACL, READ_ACL): | 
			
		
	
		
			
				
					|  |  |  |  |                     if option in info[acltype]: | 
			
		
	
		
			
				
					|  |  |  |  |                         info[acltype].remove(option) | 
			
		
	
		
			
				
					|  |  |  |  |         return info | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def move_user_to_alumni(self, user): | 
			
		
	
		
			
				
					|  |  |  |  |         """ moves a user to the alumni group and removes every access rights """ | 
			
		
	
		
			
				
					|  |  |  |  |         for access_to in user.write_acl: | 
			
		
	
	
		
			
				
					|  |  |  | @ -134,7 +143,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object):@@ -134,7 +143,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object): | 
			
		
	
		
			
				
					|  |  |  |  |         user.read_acl = [] | 
			
		
	
		
			
				
					|  |  |  |  |         user.group = ALUMNI | 
			
		
	
		
			
				
					|  |  |  |  |         delete_password(user.name) | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def update_user_groups(self, users): | 
			
		
	
		
			
				
					|  |  |  |  |         """ updates the config settings of the groups section """ | 
			
		
	
		
			
				
					|  |  |  |  |         groups = group_users(users) | 
			
		
	
	
		
			
				
					|  |  |  | @ -147,7 +156,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object):@@ -147,7 +156,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object): | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def write(self, fp): | 
			
		
	
		
			
				
					|  |  |  |  |         """Write an .ini-format representation of the configuration state. | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         this is adapted from the original library file. changes: | 
			
		
	
		
			
				
					|  |  |  |  |             - no default section | 
			
		
	
		
			
				
					|  |  |  |  |             - group-section at top | 
			
		
	
	
		
			
				
					|  |  |  | @ -165,7 +174,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object):@@ -165,7 +174,7 @@ class AuthzConfigParser(ConfigParser.ConfigParser, object): | 
			
		
	
		
			
				
					|  |  |  |  |                     key = " = ".join((key, str(value).replace('\n', '\n\t'))) | 
			
		
	
		
			
				
					|  |  |  |  |                 fp.write("%s\n" % (key)) | 
			
		
	
		
			
				
					|  |  |  |  |             fp.write("\n") | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |     # create configparser instance | 
			
		
	
	
		
			
				
					|  |  |  | @ -175,30 +184,30 @@ if __name__ == "__main__":@@ -175,30 +184,30 @@ if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |     # read config file | 
			
		
	
		
			
				
					|  |  |  |  |     config.read(AUTHZ_PATH) | 
			
		
	
		
			
				
					|  |  |  |  |     users = config.extract_users() | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # command line interface: | 
			
		
	
		
			
				
					|  |  |  |  |     # no option: display info | 
			
		
	
		
			
				
					|  |  |  |  |     # -g         display users in a group | 
			
		
	
		
			
				
					|  |  |  |  |     # -a         add regular user | 
			
		
	
		
			
				
					|  |  |  |  |     # -r         add restricted user | 
			
		
	
		
			
				
					|  |  |  |  |     # -m         move to alumni | 
			
		
	
		
			
				
					|  |  |  |  |     # -p         reset user password  | 
			
		
	
		
			
				
					|  |  |  |  |     # -p         reset user password | 
			
		
	
		
			
				
					|  |  |  |  |     parser = optparse.OptionParser( | 
			
		
	
		
			
				
					|  |  |  |  |                 usage="usage: %prog [option] name", | 
			
		
	
		
			
				
					|  |  |  |  |                 description="shows and manipulates svn access rights", | 
			
		
	
		
			
				
					|  |  |  |  |                 epilog="to grant a restricted user access to another folder, you have to carefully edit the authz file") | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-g", "--groupinfo", action="store_const", dest="what",  | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-g", "--groupinfo", action="store_const", dest="what", | 
			
		
	
		
			
				
					|  |  |  |  |                       const="g", help="display users in a group") | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-a", "--add", action="store_const", dest="what",  | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-a", "--add", action="store_const", dest="what", | 
			
		
	
		
			
				
					|  |  |  |  |                       const="a", help="add a regular user") | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-r", "--restricted", action="store_const", dest="what",  | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-r", "--restricted", action="store_const", dest="what", | 
			
		
	
		
			
				
					|  |  |  |  |                       const="r", help="add a restricted user") | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-m", "--move", action="store_const", dest="what",  | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-m", "--move", action="store_const", dest="what", | 
			
		
	
		
			
				
					|  |  |  |  |                       const="m", help="move a user to alumni") | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-p", "--password", action="store_const", dest="what",  | 
			
		
	
		
			
				
					|  |  |  |  |     parser.add_option("-p", "--password", action="store_const", dest="what", | 
			
		
	
		
			
				
					|  |  |  |  |                       const="p", help="reset a user password") | 
			
		
	
		
			
				
					|  |  |  |  |     options, args = parser.parse_args() | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if len(args)==0: | 
			
		
	
		
			
				
					|  |  |  |  |         # no arguments? then display all the users! | 
			
		
	
		
			
				
					|  |  |  |  |         groups = group_users(users) | 
			
		
	
	
		
			
				
					|  |  |  | @ -207,12 +216,12 @@ if __name__ == "__main__":@@ -207,12 +216,12 @@ if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |             for name in sorted(usernames): | 
			
		
	
		
			
				
					|  |  |  |  |                 print "  " + name | 
			
		
	
		
			
				
					|  |  |  |  |         sys.exit() | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if len(args)>1: | 
			
		
	
		
			
				
					|  |  |  |  |         # more than one usename? not here, john boy | 
			
		
	
		
			
				
					|  |  |  |  |         sys.exit("please provide only one name") | 
			
		
	
		
			
				
					|  |  |  |  |     name = args[0] | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if options.what == "g": | 
			
		
	
		
			
				
					|  |  |  |  |         # show group information | 
			
		
	
		
			
				
					|  |  |  |  |         groups = group_users(users) | 
			
		
	
	
		
			
				
					|  |  |  | @ -222,7 +231,7 @@ if __name__ == "__main__":@@ -222,7 +231,7 @@ if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |         for usernamename in sorted(groups[name]): | 
			
		
	
		
			
				
					|  |  |  |  |             print "  " + usernamename | 
			
		
	
		
			
				
					|  |  |  |  |         sys.exit() | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if options.what in ("a", "r"): | 
			
		
	
		
			
				
					|  |  |  |  |         # add a user, restricted or regular | 
			
		
	
		
			
				
					|  |  |  |  |         if name in users: | 
			
		
	
	
		
			
				
					|  |  |  | @ -244,7 +253,7 @@ if __name__ == "__main__":@@ -244,7 +253,7 @@ if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |     if name not in users: | 
			
		
	
		
			
				
					|  |  |  |  |         sys.exit("User '%s' not found, use this without a name to get a list of users." % name) | 
			
		
	
		
			
				
					|  |  |  |  |     user = users[name] | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if options.what == "m": | 
			
		
	
		
			
				
					|  |  |  |  |         # move user to alumni | 
			
		
	
		
			
				
					|  |  |  |  |         groups = group_users(users) | 
			
		
	
	
		
			
				
					|  |  |  | @ -262,7 +271,7 @@ if __name__ == "__main__":@@ -262,7 +271,7 @@ if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |         password = set_new_password(name) | 
			
		
	
		
			
				
					|  |  |  |  |         print "New password for user '%s': '%s'" % (name, password) | 
			
		
	
		
			
				
					|  |  |  |  |         sys.exit() | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # no option, just a name: | 
			
		
	
		
			
				
					|  |  |  |  |     # print all the infos connected to a name | 
			
		
	
		
			
				
					|  |  |  |  |     print "User %s is in group '%s':" % (name, user.group) | 
			
		
	
	
		
			
				
					|  |  |  | @ -282,7 +291,13 @@ if __name__ == "__main__":@@ -282,7 +291,13 @@ if __name__ == "__main__": | 
			
		
	
		
			
				
					|  |  |  |  |         print "  Read access is NOT granted to any folder" | 
			
		
	
		
			
				
					|  |  |  |  |     info = config.get_folder_info(name) | 
			
		
	
		
			
				
					|  |  |  |  |     print "Labjornal %s%s:" % (SVN_BASE, name) | 
			
		
	
		
			
				
					|  |  |  |  |     write_acl = [ "@" + ADMINS ] + info[WRITE_ACL] | 
			
		
	
		
			
				
					|  |  |  |  |     print "  Write access granted to " + ", ".join(write_acl) | 
			
		
	
		
			
				
					|  |  |  |  |     read_acl = [ "@" + ADMINS, "@" + REGULAR ] + info[READ_ACL] | 
			
		
	
		
			
				
					|  |  |  |  |     print "  Read access granted to: " + ", ".join(read_acl) | 
			
		
	
		
			
				
					|  |  |  |  |     if info[WRITE_ACL]: | 
			
		
	
		
			
				
					|  |  |  |  |         print "  Write and read access granted to: " + ", ".join(info[WRITE_ACL]) | 
			
		
	
		
			
				
					|  |  |  |  |     else: | 
			
		
	
		
			
				
					|  |  |  |  |         print "  No write access granted to anybody" | 
			
		
	
		
			
				
					|  |  |  |  |     if info[READ_ACL]: | 
			
		
	
		
			
				
					|  |  |  |  |         print "  Read access granted to: " + ", ".join(info[READ_ACL]) | 
			
		
	
		
			
				
					|  |  |  |  |     else: | 
			
		
	
		
			
				
					|  |  |  |  |         print "  No read access granted to anybody" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |