From d7148b1711cf9ceee6aa5f5294a7d57f4f948d19 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Thu, 31 Oct 2013 18:17:26 -0400 Subject: [PATCH] Start on controllers and the API for organizations. Also adds fake model methods --- data/model.py | 40 ++++++++++++++++++++++++++++++++++++++-- endpoints/api.py | 39 ++++++++++++++++++++++++++++++++++++++- endpoints/web.py | 1 + static/js/app.js | 5 +++++ static/js/controllers.js | 17 +++++++++++++++++ 5 files changed, 99 insertions(+), 3 deletions(-) diff --git a/data/model.py b/data/model.py index a46ca1912..36d0568b8 100644 --- a/data/model.py +++ b/data/model.py @@ -166,17 +166,53 @@ def verify_user(username, password): # We weren't able to authorize the user return None +class dotdict(dict): + def __getattr__(self, name): + return self[name] + + +def get_user_organizations(username): + # TODO: return the orgs that the user is apart of. + return [dotdict({ + 'username': 'testorg', + 'email': 'testorg@quay.io' + })] + + +def lookup_organization(name, username=None): + if name == 'testorg': + return dotdict({ + 'username': 'testorg', + 'email': 'testorg@quay.io' + }) + + return None + + +def get_user_teams(username, organization): + # TODO: return the teams that the user is apart of. + return [dotdict({ + 'id': 1234, + 'name': 'Owners' + })] + def get_visible_repositories(username=None, include_public=True, limit=None, - sort=False): + sort=False, namespace=None): if not username and not include_public: return [] - query = Repository.select().distinct().join(Visibility) + query = Repository.select().distinct() + + if namespace: + query = query.where(Repository.namespace == namespace) + + query = query.join(Visibility) or_clauses = [] if include_public: or_clauses.append((Visibility.name == 'public')) + if username: with_perms = query.switch(Repository).join(RepositoryPermission, JOIN_LEFT_OUTER) diff --git a/endpoints/api.py b/endpoints/api.py index 853c7498f..1ebe4f2a2 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -53,10 +53,18 @@ def welcome(): @app.route('/api/user/', methods=['GET']) def get_logged_in_user(): + def org_view(o): + return { + 'name': o.username, + 'gravatar': compute_hash(o.email), + } + if current_user.is_anonymous(): return jsonify({'anonymous': True}) user = current_user.db_user() + organizations = model.get_user_organizations(user.username) + return jsonify({ 'verified': user.verified, 'anonymous': False, @@ -64,8 +72,10 @@ def get_logged_in_user(): 'email': user.email, 'gravatar': compute_hash(user.email), 'askForPassword': user.password_hash is None, + 'organizations': [org_view(o) for o in organizations] }) + @app.route('/api/user/', methods=['PUT']) @api_login_required def change_user_details(): @@ -179,6 +189,32 @@ user_files = UserRequestFiles(app.config['AWS_ACCESS_KEY'], app.config['AWS_SECRET_KEY'], app.config['REGISTRY_S3_BUCKET']) +@app.route('/api/organization/', methods=['GET']) +def get_organization(orgname): + def team_view(t): + return { + 'id': t.id, + 'name': t.name + } + + def org_view(o, teams): + return { + 'name': o.username, + 'gravatar': compute_hash(o.email), + 'teams': [team_view(t) for t in teams] + } + + if current_user.is_anonymous(): + abort(404) + + user = current_user.db_user() + organization = model.lookup_organization(orgname, username = user.username) + if not organization: + abort(404) + + teams = model.get_user_teams(user.username, organization) + return jsonify(org_view(organization, teams)) + @app.route('/api/repository', methods=['POST']) @api_login_required @@ -236,6 +272,7 @@ def list_repos_api(): } limit = request.args.get('limit', None) + namespace_filter = request.args.get('namespace', None) include_public = request.args.get('public', 'true') include_private = request.args.get('private', 'true') sort = request.args.get('sort', 'false') @@ -255,7 +292,7 @@ def list_repos_api(): repo_query = model.get_visible_repositories(username, limit=limit, include_public=include_public, - sort=sort) + sort=sort, namespace=namespace_filter) repos = [repo_view(repo) for repo in repo_query] response = { 'repositories': repos diff --git a/endpoints/web.py b/endpoints/web.py index ddfbca3d6..c1c59674a 100644 --- a/endpoints/web.py +++ b/endpoints/web.py @@ -43,6 +43,7 @@ def load_user(username): @app.route('/', methods=['GET'], defaults={'path': ''}) @app.route('/repository/', methods=['GET']) +@app.route('/organization/', methods=['GET']) def index(path): return render_template('index.html') diff --git a/static/js/app.js b/static/js/app.js index 9d3e615be..8510fcc40 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -200,6 +200,11 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics', when('/signin/', {title: 'Signin', templateUrl: '/static/partials/signin.html', controller: SigninCtrl}). when('/new/', {title: 'Create new repository', templateUrl: '/static/partials/new-repo.html', controller: NewRepoCtrl}). + when('/organization/:orgname', {templateUrl: '/static/partials/org-view.html', controller: OrgViewCtrl}). + when('/organization/:orgname/admin', {templateUrl: '/static/partials/org-admin.html', controller: OrgAdminCtrl}). + when('/organization/:orgname/teams', {templateUrl: '/static/partials/org-teams.html', controller: OrgTeamsCtrl}). + when('/organization/:orgname/teams/:teamname', {templateUrl: '/static/partials/team-view.html', controller: TeamViewCtrl}). + when('/v1/', {title: 'Activation information', templateUrl: '/static/partials/v1-page.html', controller: V1Ctrl}). when('/', {title: 'Hosted Private Docker Registry', templateUrl: '/static/partials/landing.html', controller: LandingCtrl}). diff --git a/static/js/controllers.js b/static/js/controllers.js index 0b7a8c3f4..365c1dbca 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -1125,4 +1125,21 @@ function NewRepoCtrl($scope, $location, $http, UserService, Restangular, PlanSer // User has no subscription $scope.planRequired = PlanService.getMinimumPlan(1); }); +} + +function OrgViewCtrl($scope, Restangular, $routeParams) { + var orgname = $routeParams.orgname; +} + +function OrgAdminCtrl($scope, Restangular, $routeParams) { + var orgname = $routeParams.orgname; +} + +function OrgTeamsCtrl($scope, Restangular, $routeParams) { + var orgname = $routeParams.orgname; +} + +function TeamViewCtrl($scope, Restangular, $routeParams) { + var orgname = $routeParams.orgname; + var teamname = $routeParams.teamname; } \ No newline at end of file