Allow superusers to disable user accounts
This commit is contained in:
parent
442cbed087
commit
dc5af7496c
19 changed files with 291 additions and 37 deletions
|
@ -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.
|
||||
|
|
|
@ -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 ###
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Reference in a new issue