Beispiel #1
0
    def listGroupUsers(self, req, g):
        members = list(g.members())
        asking_user = user.User(req.session['user']['name'])
        if asking_user.is_admin:
            nonmembers = []
            usernames = user.list(asking_user)
            for username in usernames:
                if username not in members:
                    nonmembers.append(username)

            return XMLTemplateResponse("ajax/groupmembers.xml", {
                "members": members,
                "nonmembers": nonmembers,
                "group": g.name
            })

        if asking_user.name not in g.members():
            return XMLStatusResponse(
                'listGroupUsers', False,
                "You do not have permission to view this group.")

        return XMLTemplateResponse("ajax/groupmembers.xml", {
            "members": members,
            "nonmembers": [],
            "group": g.name
        })
Beispiel #2
0
 def testRemoveUser(self):
     mock_user = Mock()
     mock_user.is_admin = True
     user.add("foo", email="[email protected]", password="******")
     foo = user.User("foo")
     foo.remove()
     self.assert_("foo" not in [x for x in user.list(mock_user)])
Beispiel #3
0
 def testListUsersNonAdmin(self):
     mock_user = Mock()
     mock_user.is_admin = False
     mock_user.name = "foo"
     user.add("foo", email="[email protected]", password="******")
     users = sorted([x for x in user.list(mock_user)])
     self.assertEquals(users, ["foo"])
Beispiel #4
0
	def listUsers(self, req):
		session_user = user.User(req.session['user']['name'])
		try:
			usernames = user.list(session_user)
			return XMLTemplateResponse("ajax/listusers.xml", {'usernames': usernames})
		except Exception as e:
			return XMLStatusResponse('listUsers', False, 'Failed to get a list: %s' % e)
Beispiel #5
0
    def getpermissions(self, req, repos):
        session_user = req.session['user']
        asking_user = user.User(session_user['name'])
        path = req.post.get('getPermissions')
        branch_or_path = Path(path)
        if not repos.has_path_permissions:
            branch_or_path = branch_or_path.lstrip('/')

        perms = permissions.list_by_path(repos.name, repos.vcs_type, path)

        usernames = []
        if 'userlist' in req.post:
            usernames = user.list(asking_user)

        groupnames = []
        if 'grouplist' in req.post:
            groupnames = group.list(asking_user)

        templatevars = {
            'perms': perms,
            'repository': repos.name,
            'path': branch_or_path,
            'usernames': usernames,
            'groupnames': groupnames
        }
        return XMLTemplateResponse('ajax/repositoryperms.xml', templatevars)
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'))
Beispiel #7
0
def export_htpasswd(*args, **kwargs):
	try:
		htpasswd_file = options.env_path("htpasswd_file")
	except UnknownKeyError:
		return

	if not os.path.exists(htpasswd_file.dirname()):
		return

	with open(htpasswd_file, "w+") as htpasswd:
		for username in user.list(FakeAdminUser()):
			u = user.User(username)
			htpasswd.write("%s:%s\n" % (username, u.get_password_hash()))

	os.chmod(htpasswd_file, 0o600)
Beispiel #8
0
def export_htpasswd(*args, **kwargs):
    try:
        htpasswd_file = options.env_path("htpasswd_file")
    except UnknownKeyError:
        return

    if not os.path.exists(htpasswd_file.dirname()):
        return

    with open(htpasswd_file, "w+") as htpasswd:
        for username in user.list(FakeAdminUser()):
            u = user.User(username)
            htpasswd.write("%s:%s\n" % (username, u.get_password_hash()))

    os.chmod(htpasswd_file, 0o600)
Beispiel #9
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}
Beispiel #10
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'))
Beispiel #11
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()
Beispiel #12
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)
Beispiel #13
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))
			file(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), "w+", '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)
Beispiel #15
0
	def listGroupUsers(self, req, g):
		members = list(g.members())
		asking_user = user.User(req.session['user']['name'])
		if asking_user.is_admin:
			nonmembers = []
			usernames = user.list(asking_user)
			for username in usernames:
				if username not in members:
					nonmembers.append(username)

			return XMLTemplateResponse("ajax/groupmembers.xml",
					{"members": members, "nonmembers": nonmembers,
						"group": g.name})

		if asking_user.name not in g.members():
			return XMLStatusResponse('listGroupUsers', False,
				"You do not have permission to view this group.")

		return XMLTemplateResponse("ajax/groupmembers.xml",
				{"members": members, "nonmembers": [],
					"group": g.name})
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))
Beispiel #17
0
	def getpermissions(self, req, repos):
		session_user = req.session['user']
		asking_user = user.User(session_user['name'])
		path = req.post.get('getPermissions')
		branch_or_path = Path(path)
		if not repos.has_path_permissions:
			branch_or_path = branch_or_path.lstrip('/')

		perms = permissions.list_by_path(repos.name,
				repos.vcs_type, path)

		usernames = []
		if 'userlist' in req.post:
			usernames = user.list(asking_user)

		groupnames = []
		if 'grouplist' in req.post:
			groupnames = group.list(asking_user)

		templatevars = {'perms': perms, 'repository': repos.name,
			'path': branch_or_path, 'usernames': usernames,
			'groupnames': groupnames}
		return XMLTemplateResponse('ajax/repositoryperms.xml', templatevars)
Beispiel #18
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))
Beispiel #19
0
 def testListUsersAdmin(self):
     mock_user = Mock()
     mock_user.is_admin = True
     user.add("foo", email="[email protected]", password="******")
     users = sorted([x for x in user.list(mock_user)])
     self.assertEquals(users, ["foo", "test"])