Merge branch 'master' into comewithmeifyouwanttowork
This commit is contained in:
commit
3b72b26836
62 changed files with 923 additions and 714 deletions
|
@ -17,6 +17,8 @@ SCHEME_DRIVERS = {
|
|||
'mysql': MySQLDatabase,
|
||||
'mysql+pymysql': MySQLDatabase,
|
||||
'sqlite': SqliteDatabase,
|
||||
'postgresql': PostgresqlDatabase,
|
||||
'postgresql+psycopg2': PostgresqlDatabase,
|
||||
}
|
||||
|
||||
db = Proxy()
|
||||
|
@ -32,7 +34,7 @@ def _db_from_url(url, db_kwargs):
|
|||
if parsed_url.username:
|
||||
db_kwargs['user'] = parsed_url.username
|
||||
if parsed_url.password:
|
||||
db_kwargs['passwd'] = parsed_url.password
|
||||
db_kwargs['password'] = parsed_url.password
|
||||
|
||||
return SCHEME_DRIVERS[parsed_url.drivername](parsed_url.database, **db_kwargs)
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
"""add log kind for regenerating robot tokens
|
||||
|
||||
Revision ID: 43e943c0639f
|
||||
Revises: 82297d834ad
|
||||
Create Date: 2014-08-25 17:14:42.784518
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '43e943c0639f'
|
||||
down_revision = '82297d834ad'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
from data.model.sqlalchemybridge import gen_sqlalchemy_metadata
|
||||
from data.database import all_models
|
||||
|
||||
|
||||
def upgrade():
|
||||
schema = gen_sqlalchemy_metadata(all_models)
|
||||
|
||||
op.bulk_insert(schema.tables['logentrykind'],
|
||||
[
|
||||
{'id': 41, 'name':'regenerate_robot_token'},
|
||||
])
|
||||
|
||||
|
||||
def downgrade():
|
||||
schema = gen_sqlalchemy_metadata(all_models)
|
||||
|
||||
logentrykind = schema.tables['logentrykind']
|
||||
op.execute(
|
||||
(logentrykind.delete()
|
||||
.where(logentrykind.c.name == op.inline_literal('regenerate_robot_token')))
|
||||
|
||||
)
|
|
@ -20,12 +20,12 @@ def get_id(query):
|
|||
|
||||
def upgrade():
|
||||
conn = op.get_bind()
|
||||
event_id = get_id('Select id From externalnotificationevent Where name="repo_push" Limit 1')
|
||||
method_id = get_id('Select id From externalnotificationmethod Where name="webhook" Limit 1')
|
||||
event_id = get_id('Select id From externalnotificationevent Where name=\'repo_push\' Limit 1')
|
||||
method_id = get_id('Select id From externalnotificationmethod Where name=\'webhook\' Limit 1')
|
||||
conn.execute('Insert Into repositorynotification (uuid, repository_id, event_id, method_id, config_json) Select public_id, repository_id, %s, %s, parameters FROM webhook' % (event_id, method_id))
|
||||
|
||||
def downgrade():
|
||||
conn = op.get_bind()
|
||||
event_id = get_id('Select id From externalnotificationevent Where name="repo_push" Limit 1')
|
||||
method_id = get_id('Select id From externalnotificationmethod Where name="webhook" Limit 1')
|
||||
event_id = get_id('Select id From externalnotificationevent Where name=\'repo_push\' Limit 1')
|
||||
method_id = get_id('Select id From externalnotificationmethod Where name=\'webhook\' Limit 1')
|
||||
conn.execute('Insert Into webhook (public_id, repository_id, parameters) Select uuid, repository_id, config_json FROM repositorynotification Where event_id=%s And method_id=%s' % (event_id, method_id))
|
||||
|
|
|
@ -203,7 +203,7 @@ def upgrade():
|
|||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||
sa.Column('service_id', sa.Integer(), nullable=False),
|
||||
sa.Column('service_ident', sa.String(length=255, collation='utf8_general_ci'), nullable=False),
|
||||
sa.Column('service_ident', sa.String(length=255), nullable=False),
|
||||
sa.ForeignKeyConstraint(['service_id'], ['loginservice.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
|
@ -375,7 +375,7 @@ def upgrade():
|
|||
sa.Column('command', sa.Text(), nullable=True),
|
||||
sa.Column('repository_id', sa.Integer(), nullable=False),
|
||||
sa.Column('image_size', sa.BigInteger(), nullable=True),
|
||||
sa.Column('ancestors', sa.String(length=60535, collation='latin1_swedish_ci'), nullable=True),
|
||||
sa.Column('ancestors', sa.String(length=60535), nullable=True),
|
||||
sa.Column('storage_id', sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], ),
|
||||
sa.ForeignKeyConstraint(['storage_id'], ['imagestorage.id'], ),
|
||||
|
|
|
@ -76,8 +76,7 @@ class UserAlreadyInTeam(DataModelException):
|
|||
|
||||
|
||||
def is_create_user_allowed():
|
||||
return get_active_user_count() < config.app_config['LICENSE_USER_LIMIT']
|
||||
|
||||
return True
|
||||
|
||||
def create_user(username, password, email):
|
||||
""" Creates a regular user, if allowed. """
|
||||
|
@ -188,6 +187,19 @@ def create_robot(robot_shortname, parent):
|
|||
except Exception as ex:
|
||||
raise DataModelException(ex.message)
|
||||
|
||||
def get_robot(robot_shortname, parent):
|
||||
robot_username = format_robot_username(parent.username, robot_shortname)
|
||||
robot = lookup_robot(robot_username)
|
||||
|
||||
if not robot:
|
||||
msg = ('Could not find robot with username: %s' %
|
||||
robot_username)
|
||||
raise InvalidRobotException(msg)
|
||||
|
||||
service = LoginService.get(name='quayrobot')
|
||||
login = FederatedLogin.get(FederatedLogin.user == robot, FederatedLogin.service == service)
|
||||
|
||||
return robot, login.service_ident
|
||||
|
||||
def lookup_robot(robot_username):
|
||||
joined = User.select().join(FederatedLogin).join(LoginService)
|
||||
|
@ -198,7 +210,6 @@ 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,
|
||||
|
@ -211,6 +222,25 @@ def verify_robot(robot_username, password):
|
|||
|
||||
return found[0]
|
||||
|
||||
def regenerate_robot_token(robot_shortname, parent):
|
||||
robot_username = format_robot_username(parent.username, robot_shortname)
|
||||
|
||||
robot = lookup_robot(robot_username)
|
||||
if not robot:
|
||||
raise InvalidRobotException('Could not find robot with username: %s' %
|
||||
robot_username)
|
||||
|
||||
password = random_string_generator(length=64)()
|
||||
robot.email = password
|
||||
|
||||
service = LoginService.get(name='quayrobot')
|
||||
login = FederatedLogin.get(FederatedLogin.user == robot, FederatedLogin.service == service)
|
||||
login.service_ident = password
|
||||
|
||||
login.save()
|
||||
robot.save()
|
||||
|
||||
return robot, password
|
||||
|
||||
def delete_robot(robot_username):
|
||||
try:
|
||||
|
@ -872,6 +902,34 @@ def get_all_repo_users(namespace_name, repository_name):
|
|||
Repository.name == repository_name)
|
||||
|
||||
|
||||
def get_all_repo_users_transitive_via_teams(namespace_name, repository_name):
|
||||
select = User.select().distinct()
|
||||
with_team_member = select.join(TeamMember)
|
||||
with_team = with_team_member.join(Team)
|
||||
with_perm = with_team.join(RepositoryPermission)
|
||||
with_repo = with_perm.join(Repository)
|
||||
return with_repo.where(Repository.namespace == namespace_name,
|
||||
Repository.name == repository_name)
|
||||
|
||||
|
||||
def get_all_repo_users_transitive(namespace_name, repository_name):
|
||||
# Load the users found via teams and directly via permissions.
|
||||
via_teams = get_all_repo_users_transitive_via_teams(namespace_name, repository_name)
|
||||
directly = [perm.user for perm in get_all_repo_users(namespace_name, repository_name)]
|
||||
|
||||
# Filter duplicates.
|
||||
user_set = set()
|
||||
|
||||
def check_add(u):
|
||||
if u.username in user_set:
|
||||
return False
|
||||
|
||||
user_set.add(u.username)
|
||||
return True
|
||||
|
||||
return [user for user in list(directly) + list(via_teams) if check_add(user)]
|
||||
|
||||
|
||||
def get_repository_for_resource(resource_key):
|
||||
try:
|
||||
return (Repository
|
||||
|
@ -1706,19 +1764,20 @@ def create_notification(kind_name, target, metadata={}):
|
|||
|
||||
def create_unique_notification(kind_name, target, metadata={}):
|
||||
with config.app_config['DB_TRANSACTION_FACTORY'](db):
|
||||
if list_notifications(target, kind_name).count() == 0:
|
||||
if list_notifications(target, kind_name, limit=1).count() == 0:
|
||||
create_notification(kind_name, target, metadata)
|
||||
|
||||
|
||||
def lookup_notification(user, uuid):
|
||||
results = list(list_notifications(user, id_filter=uuid, include_dismissed=True))
|
||||
results = list(list_notifications(user, id_filter=uuid, include_dismissed=True, limit=1))
|
||||
if not results:
|
||||
return None
|
||||
|
||||
return results[0]
|
||||
|
||||
|
||||
def list_notifications(user, kind_name=None, id_filter=None, include_dismissed=False):
|
||||
def list_notifications(user, kind_name=None, id_filter=None, include_dismissed=False,
|
||||
page=None, limit=None):
|
||||
Org = User.alias()
|
||||
AdminTeam = Team.alias()
|
||||
AdminTeamMember = TeamMember.alias()
|
||||
|
@ -1756,6 +1815,11 @@ def list_notifications(user, kind_name=None, id_filter=None, include_dismissed=F
|
|||
.switch(Notification)
|
||||
.where(Notification.uuid == id_filter))
|
||||
|
||||
if page:
|
||||
query = query.paginate(page, limit)
|
||||
elif limit:
|
||||
query = query.limit(limit)
|
||||
|
||||
return query
|
||||
|
||||
|
||||
|
|
Reference in a new issue