- 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:
Mike Bonnet 2007-03-19 17:27:48 -04:00
parent 73e2a50113
commit acd7cde21c
4 changed files with 59 additions and 49 deletions

View file

@ -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):

View file

@ -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')

View file

@ -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)

View file

@ -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