- centralize user creation in the Session class
- check user status on login as well as session creation - don't even create sessions for blocked users
This commit is contained in:
parent
73e2a50113
commit
acd7cde21c
4 changed files with 59 additions and 49 deletions
6
cli/koji
6
cli/koji
|
|
@ -1045,19 +1045,19 @@ def handle_add_user(options, session, args):
|
|||
usage += _("\n(Specify the --help global option for a list of other help options)")
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("--principal", help=_("The Kerberos principal for this user"))
|
||||
parser.add_option("--disabled", help=_("Prohibit logins by this user"), action="store_true")
|
||||
parser.add_option("--disable", help=_("Prohibit logins by this user"), action="store_true")
|
||||
(options, args) = parser.parse_args(args)
|
||||
if len(args) < 1:
|
||||
parser.error(_("You must specify the username of the user to add"))
|
||||
elif len(args) > 1:
|
||||
parser.error(_("This command only accepts one argument (username)"))
|
||||
username = args[0]
|
||||
if options.disabled:
|
||||
if options.disable:
|
||||
status = koji.USER_STATUS['BLOCKED']
|
||||
else:
|
||||
status = koji.USER_STATUS['NORMAL']
|
||||
activate_session(session)
|
||||
user_id = session.addUser(username, status=status, krb_principal=options.principal)
|
||||
user_id = session.createUser(username, status=status, krb_principal=options.principal)
|
||||
print "Added user %s (%i)" % (username, user_id)
|
||||
|
||||
def handle_enable_user(options, session, args):
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ CREATE TABLE users (
|
|||
id SERIAL NOT NULL PRIMARY KEY,
|
||||
name VARCHAR(255) UNIQUE NOT NULL,
|
||||
password VARCHAR(255),
|
||||
status INTEGER,
|
||||
usertype INTEGER,
|
||||
status INTEGER NOT NULL,
|
||||
usertype INTEGER NOT NULL,
|
||||
krb_principal VARCHAR(255) UNIQUE
|
||||
) WITHOUT OIDS;
|
||||
|
||||
|
|
@ -598,7 +598,7 @@ rpminfo, rpmdeps,
|
|||
rpmfiles TO PUBLIC;
|
||||
|
||||
-- example code to add initial admins
|
||||
-- insert into users (name, usertype, krb_principal) values ('admin', 0, 'admin@EXAMPLE.COM');
|
||||
-- insert into users (name, usertype, status, krb_principal) values ('admin', 0, 0, 'admin@EXAMPLE.COM');
|
||||
-- insert into user_perms (user_id, perm_id)
|
||||
-- select users.id, permissions.id from users, permissions
|
||||
-- where users.name in ('admin')
|
||||
|
|
|
|||
|
|
@ -3558,15 +3558,9 @@ def get_build_notifications(user_id):
|
|||
|
||||
def new_group(name):
|
||||
"""Add a user group to the database"""
|
||||
context.session.assertPerm('admin')
|
||||
if get_user(name):
|
||||
raise koji.GenericError, 'user/group already exists: %s' % name
|
||||
group_id = _singleValue("SELECT nextval('users_id_seq')", strict=True)
|
||||
usertype = koji.USERTYPES['GROUP']
|
||||
insert = """INSERT INTO users (id, name, password, usertype)
|
||||
VALUES (%(group_id)i, %(name)s, NULL, %(usertype)i)"""
|
||||
_dml(insert, locals())
|
||||
return group_id
|
||||
return context.session.createUser(name, usertype=koji.USERTYPES['GROUP'])
|
||||
|
||||
def add_group_member(group,user):
|
||||
"""Add user to group"""
|
||||
|
|
@ -3621,6 +3615,7 @@ def get_group_members(group):
|
|||
return _multiRow(q, locals(), fields)
|
||||
|
||||
def set_user_status(user, status):
|
||||
context.session.assertPerm('admin')
|
||||
if not koji.USER_STATUS.get(status):
|
||||
raise koji.GenericError, 'invalid status: %s' % status
|
||||
if user['status'] == status:
|
||||
|
|
@ -4717,28 +4712,17 @@ class RootExports(object):
|
|||
VALUES (%(user_id)i, %(perm_id)i)"""
|
||||
_dml(insert, locals())
|
||||
|
||||
def addUser(self, username, password=None, status=None, krb_principal=None):
|
||||
def createUser(self, username, status=None, krb_principal=None):
|
||||
"""Add a user to the database"""
|
||||
|
||||
context.session.assertPerm('admin')
|
||||
if get_user(username):
|
||||
raise koji.GenericError, 'user already exists: %s' % username
|
||||
if krb_principal and get_user(krb_principal):
|
||||
raise koji.GenericError, 'user with this Kerberos principal already exists: %s' % krb_principal
|
||||
c = context.cnx.cursor()
|
||||
userID = koji.get_sequence_value(c, 'users_id_seq')
|
||||
userType = koji.USERTYPES['NORMAL']
|
||||
if status == None:
|
||||
status = koji.USER_STATUS['NORMAL']
|
||||
insert = """INSERT INTO users (id, name, password, usertype, status, krb_principal)
|
||||
VALUES (%(userID)i, %(username)s, %(password)s, %(userType)i, %(status)i, %(krb_principal)s)"""
|
||||
context.commit_pending = True
|
||||
c.execute(insert, locals())
|
||||
return userID
|
||||
|
||||
return context.session.createUser(username, status=status, krb_principal=krb_principal)
|
||||
|
||||
def enableUser(self, username):
|
||||
"""Enable logins by the specified user"""
|
||||
context.session.assertPerm('admin')
|
||||
user = get_user(username)
|
||||
if not user:
|
||||
raise koji.GenericError, 'unknown user: %s' % username
|
||||
|
|
@ -4746,7 +4730,6 @@ class RootExports(object):
|
|||
|
||||
def disableUser(self, username):
|
||||
"""Disable logins by the specified user"""
|
||||
context.session.assertPerm('admin')
|
||||
user = get_user(username)
|
||||
if not user:
|
||||
raise koji.GenericError, 'unknown user: %s' % username
|
||||
|
|
@ -5035,21 +5018,17 @@ class RootExports(object):
|
|||
|
||||
def addHost(self, hostname, arches, krb_principal=None):
|
||||
"""Add a host to the database"""
|
||||
|
||||
context.session.assertPerm('admin')
|
||||
if get_host(hostname):
|
||||
raise koji.GenericError, 'host already exists: %s' % hostname
|
||||
q = """SELECT id FROM channels WHERE name = 'default'"""
|
||||
default_channel = _singleValue(q)
|
||||
#users entry
|
||||
userID = _singleValue("SELECT nextval('users_id_seq')", strict=True)
|
||||
userType = koji.USERTYPES['HOST']
|
||||
if krb_principal is None:
|
||||
fmt = context.opts.get('HostPrincipalFormat','compile/%s@EXAMPLE.COM')
|
||||
krb_principal = fmt % hostname
|
||||
insert = """INSERT INTO users (id, name, password, usertype, krb_principal)
|
||||
VALUES (%(userID)i, %(hostname)s, null, %(userType)i, %(krb_principal)s)"""
|
||||
_dml(insert, locals())
|
||||
#users entry
|
||||
userID = context.session.createUser(hostname, usertype=koji.USERTYPES['HOST'],
|
||||
krb_principal=krb_principal)
|
||||
#host entry
|
||||
hostID = _singleValue("SELECT nextval('host_id_seq')", strict=True)
|
||||
arches = " ".join(arches)
|
||||
|
|
@ -5062,7 +5041,6 @@ class RootExports(object):
|
|||
_dml(insert, locals())
|
||||
return hostID
|
||||
|
||||
|
||||
def enableHost(self, hostname):
|
||||
"""Mark a host as enabled"""
|
||||
set_host_enabled(hostname, True)
|
||||
|
|
|
|||
58
koji/auth.py
58
koji/auth.py
|
|
@ -122,8 +122,8 @@ class Session(object):
|
|||
c.execute(q,session_data)
|
||||
user_data = dict(zip(fields,c.fetchone()))
|
||||
|
||||
if user_data['status'] == koji.USER_STATUS['BLOCKED']:
|
||||
raise koji.AuthError, 'User not allowed'
|
||||
if user_data['status'] != koji.USER_STATUS['NORMAL']:
|
||||
raise koji.AuthError, 'logins by %s are not allowed' % user_data['name']
|
||||
#check for exclusive sessions
|
||||
if session_data['exclusive']:
|
||||
#we are the exclusive session for this user
|
||||
|
|
@ -209,6 +209,19 @@ class Session(object):
|
|||
raise koji.AuthLockError, self.lockerror
|
||||
return True
|
||||
|
||||
def checkLoginAllowed(self, user_id):
|
||||
"""Verify that the user is allowed to login"""
|
||||
cursor = context.cnx.cursor()
|
||||
query = """SELECT name, usertype, status FROM users WHERE id = %(user_id)i"""
|
||||
cursor.execute(query, locals())
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
raise koji.AuthError, 'invalid user_id: %s' % user_id
|
||||
name, usertype, status = result
|
||||
|
||||
if status != koji.USER_STATUS['NORMAL']:
|
||||
raise koji.AuthError, 'logins by %s are not allowed' % name
|
||||
|
||||
def login(self,user,password,opts=None):
|
||||
"""create a login session"""
|
||||
if opts is None:
|
||||
|
|
@ -225,13 +238,15 @@ class Session(object):
|
|||
|
||||
# check passwd
|
||||
c = context.cnx.cursor()
|
||||
q = """SELECT id,status,usertype FROM users
|
||||
q = """SELECT id FROM users
|
||||
WHERE name = %(user)s AND password = %(password)s"""
|
||||
c.execute(q,locals())
|
||||
r = c.fetchone()
|
||||
if not r:
|
||||
raise koji.AuthError, 'invalid username or password'
|
||||
(user_id,status,usertype) = r
|
||||
user_id = r[0]
|
||||
|
||||
self.checkLoginAllowed(user_id)
|
||||
|
||||
#create session and return
|
||||
sinfo = self.createSession(user_id, hostip, koji.AUTHTYPE_NORMAL)
|
||||
|
|
@ -281,6 +296,8 @@ class Session(object):
|
|||
else:
|
||||
raise koji.AuthError, 'Unknown Kerberos principal: %s' % login_principal
|
||||
|
||||
self.checkLoginAllowed(user_id)
|
||||
|
||||
hostip = context.req.connection.remote_ip
|
||||
if hostip == '127.0.0.1':
|
||||
hostip = socket.gethostbyname(socket.gethostname())
|
||||
|
|
@ -350,18 +367,19 @@ class Session(object):
|
|||
username = client_name
|
||||
|
||||
cursor = context.cnx.cursor()
|
||||
query = """SELECT id, status FROM users
|
||||
query = """SELECT id FROM users
|
||||
WHERE name = %(username)s"""
|
||||
cursor.execute(query, locals())
|
||||
result = cursor.fetchone()
|
||||
if result:
|
||||
user_id, status = result
|
||||
user_id = result[0]
|
||||
else:
|
||||
if context.opts['LoginCreatesUser'].lower() in ('yes', 'on', 'true', '1'):
|
||||
user_id = self.createUser(username, koji.USERTYPES['NORMAL'], None)
|
||||
status = None
|
||||
user_id = self.createUser(username)
|
||||
else:
|
||||
raise koji.AuthError, 'Unknown user: %s' % username
|
||||
|
||||
self.checkLoginAllowed(user_id)
|
||||
|
||||
hostip = context.req.connection.remote_ip
|
||||
if hostip == '127.0.0.1':
|
||||
|
|
@ -541,18 +559,33 @@ class Session(object):
|
|||
else:
|
||||
return None
|
||||
|
||||
def createUser(self, name, usertype, krb_principal):
|
||||
def createUser(self, name, usertype=None, status=None, krb_principal=None):
|
||||
"""
|
||||
Create a new user, using the provided values.
|
||||
Return the user_id of the newly-created user.
|
||||
"""
|
||||
self.assertPerm('admin')
|
||||
|
||||
if not name:
|
||||
raise koji.GenericError, 'a user must have a non-empty name'
|
||||
|
||||
if usertype == None:
|
||||
usertype = koji.USERTYPES['NORMAL']
|
||||
elif not koji.USERTYPES.get(usertype):
|
||||
raise koji.GenericError, 'invalid user type: %s' % usertype
|
||||
|
||||
if status == None:
|
||||
status = koji.USER_STATUS['NORMAL']
|
||||
elif not koji.USER_STATUS.get(status):
|
||||
raise koji.GenericError, 'invalid status: %s' % status
|
||||
|
||||
cursor = context.cnx.cursor()
|
||||
select = """SELECT nextval('users_id_seq')"""
|
||||
cursor.execute(select, locals())
|
||||
user_id = cursor.fetchone()[0]
|
||||
|
||||
insert = """INSERT INTO users (id, name, usertype, krb_principal)
|
||||
VALUES (%(user_id)i, %(name)s, %(usertype)i, %(krb_principal)s)"""
|
||||
insert = """INSERT INTO users (id, name, usertype, status, krb_principal)
|
||||
VALUES (%(user_id)i, %(name)s, %(usertype)i, %(status)i, %(krb_principal)s)"""
|
||||
cursor.execute(insert, locals())
|
||||
context.cnx.commit()
|
||||
|
||||
|
|
@ -566,9 +599,8 @@ class Session(object):
|
|||
if atidx == -1:
|
||||
raise koji.AuthError, 'invalid Kerberos principal: %s' % krb_principal
|
||||
user_name = krb_principal[:atidx]
|
||||
user_type = koji.USERTYPES['NORMAL']
|
||||
|
||||
return self.createUser(user_name, user_type, krb_principal)
|
||||
return self.createUser(user_name, krb_principal=krb_principal)
|
||||
|
||||
def get_user_groups(user_id):
|
||||
"""Get user groups
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue