diff --git a/data/database.py b/data/database.py index 359072268..eebea7670 100644 --- a/data/database.py +++ b/data/database.py @@ -333,6 +333,10 @@ class PermissionPrototype(BaseModel): ) +class AccessTokenKind(BaseModel): + name = CharField(unique=True, index=True) + + class AccessToken(BaseModel): friendly_name = CharField(null=True) code = CharField(default=random_string_generator(length=64), unique=True, @@ -341,6 +345,7 @@ class AccessToken(BaseModel): created = DateTimeField(default=datetime.now) role = ForeignKeyField(Role) temporary = BooleanField(default=True) + kind = ForeignKeyField(AccessTokenKind, null=True) class BuildTriggerService(BaseModel): @@ -600,4 +605,5 @@ all_models = [User, Repository, Image, AccessToken, Role, RepositoryPermission, Notification, ImageStorageLocation, ImageStoragePlacement, ExternalNotificationEvent, ExternalNotificationMethod, RepositoryNotification, RepositoryAuthorizedEmail, ImageStorageTransformation, DerivedImageStorage, - TeamMemberInvite, ImageStorageSignature, ImageStorageSignatureKind] + TeamMemberInvite, ImageStorageSignature, ImageStorageSignatureKind, + AccessTokenKind] diff --git a/data/migrations/versions/3e2d38b52a75_add_access_token_kinds_type.py b/data/migrations/versions/3e2d38b52a75_add_access_token_kinds_type.py new file mode 100644 index 000000000..53d0ae9df --- /dev/null +++ b/data/migrations/versions/3e2d38b52a75_add_access_token_kinds_type.py @@ -0,0 +1,44 @@ +"""Add access token kinds type + +Revision ID: 3e2d38b52a75 +Revises: 1d2d86d09fcd +Create Date: 2015-02-17 12:03:26.422485 + +""" + +# revision identifiers, used by Alembic. +revision = '3e2d38b52a75' +down_revision = '1d2d86d09fcd' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(tables): + ### commands auto generated by Alembic - please adjust! ### + op.create_table('accesstokenkind', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_accesstokenkind')) + ) + op.create_index('accesstokenkind_name', 'accesstokenkind', ['name'], unique=True) + op.add_column(u'accesstoken', sa.Column('kind_id', sa.Integer(), nullable=True)) + op.create_index('accesstoken_kind_id', 'accesstoken', ['kind_id'], unique=False) + op.create_foreign_key(op.f('fk_accesstoken_kind_id_accesstokenkind'), 'accesstoken', 'accesstokenkind', ['kind_id'], ['id']) + ### end Alembic commands ### + + op.bulk_insert(tables.accesstokenkind, + [ + {'id': 1, 'name':'build-worker'}, + {'id': 2, 'name':'pushpull-token'}, + ]) + + +def downgrade(tables): + ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(op.f('fk_accesstoken_kind_id_accesstokenkind'), 'accesstoken', type_='foreignkey') + op.drop_index('accesstoken_kind_id', table_name='accesstoken') + op.drop_column(u'accesstoken', 'kind_id') + op.drop_index('accesstokenkind_name', table_name='accesstokenkind') + op.drop_table('accesstokenkind') + ### end Alembic commands ### diff --git a/data/model/legacy.py b/data/model/legacy.py index deac1f02b..13b4b9471 100644 --- a/data/model/legacy.py +++ b/data/model/legacy.py @@ -15,7 +15,8 @@ from data.database import (User, Repository, Image, AccessToken, Role, Repositor RepositoryNotification, RepositoryAuthorizedEmail, TeamMemberInvite, DerivedImageStorage, ImageStorageTransformation, random_string_generator, db, BUILD_PHASE, QuayUserField, ImageStorageSignature, QueueItem, - ImageStorageSignatureKind, validate_database_url, db_for_update) + ImageStorageSignatureKind, validate_database_url, db_for_update, + AccessTokenKind) from peewee import JOIN_LEFT_OUTER, fn from util.validation import (validate_username, validate_email, validate_password, INVALID_PASSWORD_MESSAGE) @@ -1902,10 +1903,14 @@ def get_private_repo_count(username): .count()) -def create_access_token(repository, role): +def create_access_token(repository, role, kind=None, friendly_name=None): role = Role.get(Role.name == role) + kind_ref = None + if kind is not None: + kind_ref = AccessTokenKind.get(AccessTokenKind.name == kind) + new_token = AccessToken.create(repository=repository, temporary=True, - role=role) + role=role, kind=kind_ref, friendly_name=friendly_name) return new_token @@ -2024,10 +2029,10 @@ def create_repository_build(repo, access_token, job_config_obj, dockerfile_id, pull_robot = lookup_robot(pull_robot_name) return RepositoryBuild.create(repository=repo, access_token=access_token, - job_config=json.dumps(job_config_obj), - display_name=display_name, trigger=trigger, - resource_key=dockerfile_id, - pull_robot=pull_robot) + job_config=json.dumps(job_config_obj), + display_name=display_name, trigger=trigger, + resource_key=dockerfile_id, + pull_robot=pull_robot) def get_pull_robot_name(trigger): diff --git a/endpoints/common.py b/endpoints/common.py index 2f5ffc67c..9d4be7771 100644 --- a/endpoints/common.py +++ b/endpoints/common.py @@ -215,7 +215,8 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual, host = urlparse.urlparse(request.url).netloc repo_path = '%s/%s/%s' % (host, repository.namespace_user.username, repository.name) - token = model.create_access_token(repository, 'write') + token = model.create_access_token(repository, 'write', kind='build-worker', + friendly_name='Repository Build Token') logger.debug('Creating build %s with repo %s tags %s and dockerfile_id %s', build_name, repo_path, tags, dockerfile_id) diff --git a/endpoints/index.py b/endpoints/index.py index 660ab94aa..d1a902915 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -50,7 +50,7 @@ def generate_headers(role='read'): if has_token_request: repo = model.get_repository(namespace, repository) if repo: - token = model.create_access_token(repo, role) + token = model.create_access_token(repo, role, 'pushpull-token') token_str = 'signature=%s' % token.code response.headers['WWW-Authenticate'] = token_str response.headers['X-Docker-Token'] = token_str diff --git a/endpoints/trackhelper.py b/endpoints/trackhelper.py index fb99a2c2d..070927eac 100644 --- a/endpoints/trackhelper.py +++ b/endpoints/trackhelper.py @@ -34,6 +34,10 @@ def track_and_log(event_name, repo, **kwargs): elif authenticated_token: metadata['token'] = authenticated_token.friendly_name metadata['token_code'] = authenticated_token.code + + if authenticated_token.kind: + metadata['token_type'] = authenticated_token.kind.name + analytics_id = 'token:' + authenticated_token.code else: metadata['public'] = True diff --git a/initdb.py b/initdb.py index 15c62bb0b..14fcc1441 100644 --- a/initdb.py +++ b/initdb.py @@ -192,6 +192,9 @@ def initialize_database(): BuildTriggerService.create(name='github') + AccessTokenKind.create(name='build-worker') + AccessTokenKind.create(name='pushpull-token') + LogEntryKind.create(name='account_change_plan') LogEntryKind.create(name='account_change_cc') LogEntryKind.create(name='account_change_password') @@ -393,7 +396,7 @@ def populate_database(): 'Empty repository which is building.', False, [], (0, [], None)) - token = model.create_access_token(building, 'write') + token = model.create_access_token(building, 'write', 'build-worker') trigger = model.create_build_trigger(building, 'github', '123authtoken', new_user_1, pull_robot=dtrobot[0]) diff --git a/static/directives/logs-view.html b/static/directives/logs-view.html index 5038895ea..cc3c51d2f 100644 --- a/static/directives/logs-view.html +++ b/static/directives/logs-view.html @@ -56,7 +56,8 @@
-
on behalf of
diff --git a/static/js/app.js b/static/js/app.js index 63f697755..6b936a302 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -3314,7 +3314,11 @@ quayApp.directive('logsView', function () { } if (metadata.token) { - prefix += ' via token {token}'; + if (metadata.token_type == 'build-worker') { + prefix += ' by build worker'; + } else { + prefix += ' via token'; + } } else if (metadata.username) { prefix += ' by {username}'; } else { @@ -3325,7 +3329,13 @@ quayApp.directive('logsView', function () { }, 'pull_repo': function(metadata) { if (metadata.token) { - return 'Pull repository {repo} via token {token}'; + var prefix = 'Pull of repository' + if (metadata.token_type == 'build-worker') { + prefix += ' by build worker'; + } else { + prefix += ' via token'; + } + return prefix; } else if (metadata.username) { return 'Pull repository {repo} by {username}'; } else { diff --git a/test/data/test.db b/test/data/test.db index 63d2768c1..89d4b3d8c 100644 Binary files a/test/data/test.db and b/test/data/test.db differ