Fix some stuff with logins and permissions, add tags to the mode.
This commit is contained in:
parent
744c73509b
commit
08446ef59e
10 changed files with 94 additions and 34 deletions
25
auth/auth.py
25
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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__)
|
||||
|
||||
|
||||
|
|
|
@ -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')
|
||||
return send_file('templates/signin.html')
|
||||
|
|
BIN
test.db
BIN
test.db
Binary file not shown.
0
util/__init__.py
Normal file
0
util/__init__.py
Normal file
Reference in a new issue