Ejemplo n.º 1
0
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'))
Ejemplo n.º 2
0
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}
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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))
Ejemplo n.º 6
0
    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)