From 08446ef59ef88a8b4c849d4d6177ffb218809f70 Mon Sep 17 00:00:00 2001 From: yackob03 Date: Wed, 25 Sep 2013 16:46:28 -0400 Subject: [PATCH] Fix some stuff with logins and permissions, add tags to the mode. --- auth/auth.py | 25 ++------------------ auth/permissions.py | 5 +++- data/database.py | 10 +++++++- data/model.py | 49 +++++++++++++++++++++++++++++++++++++-- endpoints/api.py | 4 ++-- endpoints/index.py | 3 +-- endpoints/web.py | 32 ++++++++++++++++++++++--- test.db | Bin 36864 -> 36864 bytes util/__init__.py | 0 util.py => util/names.py | 0 10 files changed, 94 insertions(+), 34 deletions(-) create mode 100644 util/__init__.py rename util.py => util/names.py (100%) diff --git a/auth/auth.py b/auth/auth.py index 9c2ecf7dd..4b83ed7f4 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -3,38 +3,17 @@ import logging from functools import wraps from flask import request, make_response, _request_ctx_stack, abort from flask.ext.principal import identity_changed, Identity -from flask.ext.login import UserMixin from base64 import b64decode from data import model -from app import app, login_manager +from app import app -from util import parse_namespace_repository +from util.names import parse_namespace_repository logger = logging.getLogger(__name__) -class _LoginWrappedDBUser(UserMixin): - def __init__(self, db_user): - self.db_user = db_user - - def is_active(self): - return self.db_user.verified - - def get_id(self): - return unicode(self.db_user.username) - - -@login_manager.user_loader -def load_user(username): - db_user = model.get_user(username) - if db_user: - return _LoginWrappedDBUser(db_user) - else: - return None - - def get_authenticated_user(): return getattr(_request_ctx_stack.top, 'authenticated_user', None) diff --git a/auth/permissions.py b/auth/permissions.py index 4408387eb..f0e4c6f82 100644 --- a/auth/permissions.py +++ b/auth/permissions.py @@ -2,6 +2,7 @@ import logging from flask.ext.principal import identity_loaded, UserNeed, Permission from collections import namedtuple +from functools import partial from data import model from app import app @@ -11,7 +12,8 @@ from auth import get_authenticated_user, get_validated_token logger = logging.getLogger(__name__) -_RepositoryNeed = namedtuple('repository', ['namespace', 'name', 'role']) +_ResourceNeed = namedtuple('resource', ['type', 'namespace', 'name', 'role']) +_RepositoryNeed = partial(_ResourceNeed, 'repository') class ModifyRepositoryPermission(Permission): @@ -38,6 +40,7 @@ class UserPermission(Permission): @identity_loaded.connect_via(app) def on_identity_loaded(sender, identity): + logger.debug('Identity loaded: %s' % identity) # We have verified an identity, load in all of the permissions if get_authenticated_user(): identity.provides.add(UserNeed(get_authenticated_user().username)) diff --git a/data/database.py b/data/database.py index 99e9ae6fa..db2e802f1 100644 --- a/data/database.py +++ b/data/database.py @@ -18,7 +18,9 @@ class User(BaseModel): username = CharField(unique=True) password_hash = CharField() email = CharField(unique=True) - verified = BooleanField(default=False) + + # TODO move this to False and require email verification + verified = BooleanField(default=True) class Visibility(BaseModel): @@ -68,6 +70,12 @@ class Image(BaseModel): checksum = CharField(null=True) +class RepositoryTag(BaseModel): + name = CharField() + image = ForeignKeyField(Image) + repository = ForeignKeyField(Repository) + + class RepositoryImage(BaseModel): repository = ForeignKeyField(Repository) image = ForeignKeyField(Image) diff --git a/data/model.py b/data/model.py index 3015ddba5..7cdd0cfa8 100644 --- a/data/model.py +++ b/data/model.py @@ -1,8 +1,7 @@ import bcrypt import logging -from database import (User, Repository, Image, RepositoryImage, AccessToken, - RepositoryPermission, Visibility, Role) +from database import * logger = logging.getLogger(__name__) @@ -111,6 +110,52 @@ def get_repository_images(namespace_name, repository_name): Repository.namespace == namespace_name) +def list_repository_tags(namespace_name, repository_name): + select = RepositoryTag.select(RepositoryTag, Image) + with_repo = select.join(Repository) + with_image = with_repo.switch(RepositoryTag).join(Image) + return joined.where(Repository.name == repository_name and + Repository.namespace == namespace_name) + + +def get_tag_image(namespace_name, repository_name, tag_name): + joined = Image.select().join(RepositoryTag).join(Repository) + return joined.where(Repository.name == repository_name and + Repository.namespace == namespace_name and + RepositoryTag.name == tag_name) + + +def create_or_update_tag(namespace_name, repository_name, tag_name, + tag_image_id): + repo = Repository.get(Repository.name == name and + Repository.namespace == namespace) + image = Image.get(Image.image_id == tag_image_id) + + try: + tag = RepositoryTag.get(RepositoryTag.repository == repo and + RepositoryTag.tag_name == tag_name) + tag.image = image + tag.save() + except RepositoryTag.DoesNotExist: + tag = RepositoryTag.create(repository=repo, image=image, name=tag_name) + + return tag + + +def delete_tag(namespace_name, repository_name, tag_name): + repo = Repository.get(Repository.name == name and + Repository.namespace == namespace) + tag = RepositoryTag.get(RepositoryTag.repository == repo and + RepositoryTag.tag_name == tag_name) + tag.delete_instance() + + +def delete_all_repository_tags(namespace_name, repository_name): + repo = Repository.get(Repository.name == name and + Repository.namespace == namespace) + RepositoryTag.delete().where(RepositoryTag.repository == repo) + + def create_access_token(repository, user): new_token = AccessToken.create(user=user, repository=repository) return new_token diff --git a/endpoints/api.py b/endpoints/api.py index 232c77d84..4e73650ab 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -6,7 +6,7 @@ from functools import wraps from data import model from app import app -from util import parse_repository_name +from util.names import parse_repository_name logger = logging.getLogger(__name__) @@ -33,7 +33,7 @@ def list_repos_api(): 'role': repo_perm.role.name, } - repos = [repo_view(repo) + repos = [repo_view(repo) for repo in model.get_user_repositories(current_user.db_user)] response = { 'repositories': repos diff --git a/endpoints/index.py b/endpoints/index.py index f94080508..a39ce5ddb 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -10,12 +10,11 @@ from data import model from app import app from auth.auth import (process_auth, get_authenticated_user, get_validated_token) -from util import parse_namespace_repository, parse_repository_name +from util.names import parse_namespace_repository, parse_repository_name from auth.permissions import (ModifyRepositoryPermission, ReadRepositoryPermission, UserPermission) - logger = logging.getLogger(__name__) diff --git a/endpoints/web.py b/endpoints/web.py index cd76e31e2..887bb2002 100644 --- a/endpoints/web.py +++ b/endpoints/web.py @@ -1,7 +1,33 @@ -from flask import abort, send_file, redirect, request +import logging + +from flask import abort, send_file, redirect, request, url_for +from flask.ext.login import login_user, UserMixin from data import model -from app import app +from app import app, login_manager + + +logger = logging.getLogger(__name__) + + +class _LoginWrappedDBUser(UserMixin): + def __init__(self, db_user): + self.db_user = db_user + + def is_active(self): + return self.db_user.verified + + def get_id(self): + return unicode(self.db_user.username) + + +@login_manager.user_loader +def load_user(username): + db_user = model.get_user(username) + if db_user: + return _LoginWrappedDBUser(db_user) + else: + return None @app.route('/', methods=['GET']) @@ -27,4 +53,4 @@ def signin(): @app.route('/signin', methods=['GET']) def render_signin_page(): - return send_file('templates/signin.html') \ No newline at end of file + return send_file('templates/signin.html') diff --git a/test.db b/test.db index af8fed60c81d57d22cf098e61d82bf891b6f9339..45270148d205fb0ac04a2dc2ed00eca1e9b79d96 100644 GIT binary patch delta 30 mcmZozz|^pSX@WFk?L--8)>;PLN6H&h!h{()H}4j9tpNa!h{()Ht!a8tpNa