Allow superusers to disable user accounts

This commit is contained in:
Joseph Schorr 2015-05-11 17:13:42 -04:00
parent 442cbed087
commit dc5af7496c
19 changed files with 291 additions and 37 deletions

View file

@ -193,6 +193,7 @@ class User(BaseModel):
invalid_login_attempts = IntegerField(default=0)
last_invalid_login = DateTimeField(default=datetime.utcnow)
removed_tag_expiration_s = IntegerField(default=1209600) # Two weeks
enabled = BooleanField(default=True)
def delete_instance(self, recursive=False, delete_nullable=False):
# If we are deleting a robot account, only execute the subset of queries necessary.

View file

@ -0,0 +1,26 @@
"""Add enabled column to the user system
Revision ID: 154f2befdfbe
Revises: 41f4587c84ae
Create Date: 2015-05-11 17:02:43.507847
"""
# revision identifiers, used by Alembic.
revision = '154f2befdfbe'
down_revision = '41f4587c84ae'
from alembic import op
import sqlalchemy as sa
def upgrade(tables):
### commands auto generated by Alembic - please adjust! ###
op.add_column('user', sa.Column('enabled', sa.Boolean(), nullable=False, default=True))
### end Alembic commands ###
def downgrade(tables):
### commands auto generated by Alembic - please adjust! ###
op.drop_column('user', 'enabled')
### end Alembic commands ###

View file

@ -67,6 +67,7 @@ class InvalidRobotException(DataModelException):
class InvalidTeamException(DataModelException):
pass
class InvalidTeamMemberException(DataModelException):
pass
@ -259,16 +260,35 @@ def lookup_robot(robot_username):
return found[0]
def verify_robot(robot_username, password):
joined = User.select().join(FederatedLogin).join(LoginService)
found = list(joined.where(FederatedLogin.service_ident == password,
LoginService.name == 'quayrobot',
User.username == robot_username))
if not found:
result = parse_robot_username(robot_username)
if result is None:
raise InvalidRobotException('%s is an invalid robot name' % robot_username)
# Find the matching robot.
query = (User.select()
.join(FederatedLogin)
.join(LoginService)
.where(FederatedLogin.service_ident == password,
LoginService.name == 'quayrobot',
User.username == robot_username))
try:
robot = query.get()
except User.DoesNotExist:
msg = ('Could not find robot with username: %s and supplied password.' %
robot_username)
raise InvalidRobotException(msg)
return found[0]
# Find the owner user and ensure it is not disabled.
try:
owner = User.get(User.username == result[0])
except User.DoesNotExist:
raise InvalidRobotException('Robot %s owner does not exist' % robot_username)
if not owner.enabled:
raise InvalidRobotException('This user has been disabled. Please contact your administrator.')
return robot
def regenerate_robot_token(robot_shortname, parent):
robot_username = format_robot_username(parent.username, robot_shortname)

View file

@ -410,7 +410,14 @@ class UserAuthentication(object):
else:
password = decrypted
return self.state.verify_user(username_or_email, password)
(result, err_msg) = self.state.verify_user(username_or_email, password)
if not result:
return (result, err_msg)
if not result.enabled:
return (None, 'This user has been disabled. Please contact your administrator.')
return (result, err_msg)
def __getattr__(self, name):
return getattr(self.state, name, None)