def export_notifications(**kwargs): """Export a mailer.py config file For each user/repository pair, a config group is created. Only if a user has read or read/write permission to one or multiple paths in that repository, _and_ if the user has notifications enabled for that repository, _and_ if the user has a non-empty email-address. Multiple paths are grouped together by a regexp group (multiple|paths)""" bindir = options.static_path("hooks") + 'svn' # get a list of all users from submin.models import user users = [user.User(name) for name in user.list(user.FakeAdminUser())] groups = [] for u in users: if not u.email: continue u_notif = u.notifications() for repos in u_notif: repos_path = str(options.env_path("svn_dir") + repos) if not u_notif[repos]["enabled"]: continue # strip leading / paths = [ x[1:] for x in permissions.list_readable_user_paths(repos, "svn", u) ] if len(paths) == 0: continue elif len(paths) == 1: for_paths = paths[0] elif len(paths) > 0: for_paths = "(" + "|".join(paths) + ")" # Only match complete path, not partial paths (ticket #257) repos_path_re = '^' + repos_path + '$' g = { "repos_name": repos, "for_repos": repos_path_re, "email": u.email, "for_paths": for_paths, "username": u.name } groups.append(g) email = options.value( 'commit_email_from', 'Please configure commit_email_from <*****@*****.**>') templatevariables = {"groups": groups, 'from_addr': email} from submin.template.shortcuts import evaluate content = evaluate("plugins/vcs/svn/mailer.conf", templatevariables) filename = str((options.env_path() + 'conf') + 'mailer.py.conf') file(filename, 'w').writelines(content.encode('utf-8'))
def external_sync(): """Synchronizes external users""" from submin.models import user errormsgs = [] if options.value('enabled_external', 'no') == 'no': errormsgs.append('external is not enabled') return {'errormsgs': errormsgs, 'success': False} group = LDAPGroup(options.value('external_passwd'), options.value('external_user')) if not group: errormsgs.append('cannot connect to LDAP server') return {'errormsgs': errormsgs, 'success': False} group_members = group.members if not group_members: errormsgs.append('cannot find LDAP group or its members') return {'errormsgs': errormsgs, 'success': False} user_list = user.list(user.FakeAdminUser()) for username in group_members: email = group_members[username]['email'] fullname = group_members[username]['fullname'] if not validate_username(username): errormsgs.append(InvalidUsername(username)) continue if not validate_email(email): errormsgs.append(InvalidEmail(email)) continue if not validate_fullname(fullname): errormsgs.append(InvalidFullname(fullname)) fullname = username if username not in user_list: # A new user user.add(username=username, email=email, send_mail=False) user.User(username).fullname = fullname else: u = user.User(username) # Update fullname and email if necessary if (u.email, u.fullname) != (email, fullname): u.email = email u.fullname = fullname return {'errormsgs': errormsgs, 'success': True}
def run(): env_path = options.env_path() filename = os.path.expanduser("~/.ssh/authorized_keys") filename = options.value("git_dev_authorized_keysfile", filename) if not os.path.exists(os.path.dirname(filename)): try: # create dir and file if one of them doesn't exist os.mkdir(os.path.dirname(filename)) open(filename, 'a') except OSError as e: if e.errno != errno.EACCES: raise raise Exception( 'Could not write "%s", please check that git user can write it.' % filename) # Make the authorized_keys file only readable to the git-user gituser = options.value("git_user") owner = getpwnam(gituser) os.chown(os.path.dirname(filename), owner.pw_uid, owner.pw_gid) os.chmod(filename, 0o600) www_key_file = env_path + "conf" + "id_dsa.pub" if not www_key_file.exists(): raise Exception( "Could not find the submin ssh-key. Please run submin2-admin git init" ) key_fp = open(str(www_key_file)) www_key = key_fp.readline().strip() key_fp.close() # instead of writing ascii, write utf-8 encoding fp = codecs.open(str(filename), "a+", 'utf-8') env_vars = "PATH='%s' PYTHONPATH='%s'" % \ (options.value("env_path"), ':'.join(sys.path)) fp.write('command="%s submin2-admin \'%s\' git admin" %s\n' % \ (env_vars, env_path, www_key)) userlist = user.list(user.FakeAdminUser()) for x in userlist: u = user.User(x) ssh_keys = u.ssh_keys() if not ssh_keys: continue for ssh_key in ssh_keys: fp.write('command="%s submin2-admin \'%s\' git user %s" %s\n' % \ (env_vars, env_path, u, ssh_key["key"])) fp.close()
def run(reposname): failed, succeeded = [], [] errors = [] if reposname: repositories = [reposname] else: # even though we might know the username, it we can't filter on # username, as permissions might be revoked from a repository # and it won't show up if we use Repositor.list() (because it is # revoked). So regenerate for all repositories repositories = [ x['name'] for x in repository.Repository.list_all() if x['vcs'] == 'git' ] # get a list of all users + their notifications as tuples: (u, n) # We get the notifications straight away, otherwise we have to # call it user * repositories times, and the u.notifications() # function can be heavy on the database if called that many times # (for a couple of users and 36 repositories, database was hit # almost 3000 times during profiling) user_notifications = [] for name in user.list(user.FakeAdminUser()): u = user.User(name) if not u.email: # user without emails cannot be notified continue n = u.notifications() user_notifications.append((u, n)) for reposname in repositories: try: update_notification(reposname, user_notifications) except SetGitConfigError as e: errors.append(str(e)) failed.append(reposname) else: succeeded.append(reposname) if len(failed) > 0: total = len(failed) + len(succeeded) msg = "Some repositories failed to update: %s. (%s/%s)" % ( ','.join(failed), len(failed), total) raise UpdateFailed(msg)
def main(): from sys import argv, path import os path.append('_SUBMIN_LIB_DIR_') interpreter = "perl" scriptname = 'commit-email.pl' scriptdir = os.path.dirname(argv[0]) env = 'SUBMIN_LIB_DIR' if env in os.environ: path.append(os.environ[env]) if len(argv) < 4: print "Usage: %s <configfile> <repository path> <revision>" % argv[0] return os.environ['SUBMIN_ENV'] = argv[1] repospath = argv[2] rev = argv[3] from submin.models import storage storage.open() from submin.models import options bindir = options.static_path("hooks") + 'svn' from submin.models import user userlist = [user.User(name) for name in user.list(user.FakeAdminUser())] n = buildNotifications(userlist) repos = os.path.basename(repospath) if repos not in n: print "no such repository" return mailer = bindir + scriptname for email in n[repos]: os.system("%s %s '%s' '%s' -s '[%s]' '%s'" % (interpreter, mailer, repospath, rev, repos, email))
u"Ч": "CH", u"Ш": "SH", u"Щ": "SHCH", u"Ы": "Y", u"Э": "E", u"Ю": "IU", u"Я": "IA" } not_allowed_characters = re.compile('[^a-zA-Z0-9\-\/]') permission_to_name = {'rw': 'rw', 'r': 'ro', '': 'no'} report = len(sys.argv) > 0 and 'report' in sys.argv verbose = len(sys.argv) > 0 and 'verbose' in sys.argv verboseprint = print if verbose else lambda *a, **k: None groups = group.list(user.FakeAdminUser()) def get_correct_groupname(permission_by_group): """Returns correct groupname""" permission = permission_to_name[permission_by_group['permission']] path = '%s%s' % (permission_by_group['repository'], permission_by_group['path'] if permission_by_group['path'] != '/' else '') path = path.lower() for key in ru_lat: path = path.replace(key, ru_lat[key]) path = re.sub(not_allowed_characters, '', path) path = re.sub('/', '_', path)