Add ability to change the visibility of a repo, and show whether the repo is private in the repo-view screen

This commit is contained in:
Joseph Schorr 2013-09-28 17:11:10 -04:00
parent ce7620673b
commit 4382ebfd20
6 changed files with 214 additions and 11 deletions

View file

@ -165,6 +165,15 @@ def repository_is_public(namespace_name, repository_name):
return len(list(query)) > 0
def set_repository_visibility(repo, visibility):
visibility_obj = Visibility.get(name=visibility)
if not visibility_obj:
return
repo.visibility = visibility_obj
repo.save()
def create_repository(namespace, name, owner):
private = Visibility.get(name='private')
repo = Repository.create(namespace=namespace, name=name,

View file

@ -61,7 +61,7 @@ def match_repos_api(prefix):
return {
'namespace': repo.namespace,
'name': repo.name,
'description': repo.description,
'description': repo.description
}
username = current_user.db_user.username
@ -111,6 +111,23 @@ def update_repo_api(namespace, repository):
abort(404)
@app.route('/api/repository/<path:repository>/changevisibility', methods=['POST'])
@login_required
@parse_repository_name
def change_repo_visibility_api(namespace, repository):
permission = AdministerRepositoryPermission(namespace, repository)
if permission.can():
repo = model.get_repository(namespace, repository)
if repo:
values = request.get_json()
model.set_repository_visibility(repo, values['visibility'])
return jsonify({
'success': True
})
abort(404)
def image_view(image):
return {
'id': image.image_id,
@ -136,7 +153,8 @@ def get_repo_api(namespace, repository):
}
permission = ReadRepositoryPermission(namespace, repository)
if permission.can() or model.repository_is_public(namespace, repository):
is_public = model.repository_is_public(namespace, repository)
if permission.can() or is_public:
repo = model.get_repository(namespace, repository)
if repo:
tags = model.list_repository_tags(namespace, repository)
@ -150,6 +168,7 @@ def get_repo_api(namespace, repository):
'tags': tag_dict,
'can_write': can_write,
'can_admin': can_admin,
'is_public': is_public
})
abort(404) # Not fount

View file

@ -86,6 +86,33 @@ p.editable:hover i {
margin-right: 6px;
}
.repo .header .icon-container {
position: relative;
background: #eee;
padding: 4px;
border-radius: 50%;
display: inline-block;
width: 46px;
height: 46px;
text-align: center;
line-height: 38px;
margin-right: 10px;
}
.repo .header .icon-container .icon-lock {
font-size: 50%;
position: absolute;
bottom: -6px;
right: 0px;
background: rgb(253, 191, 191);
width: 20px;
display: inline-block;
border-radius: 50%;
text-align: center;
height: 20px;
line-height: 21px;
}
.repo .description {
margin-bottom: 40px;
}
@ -272,6 +299,56 @@ p.editable:hover i {
width: 54px;
}
.repo-admin .repo-access-state .state-icon {
text-align: center;
margin-bottom: 10px;
}
.repo-admin .repo-access-state .state-icon i {
font-size: 46px;
width: 54px;
height: 54px;
line-height: 54px;
border-radius: 50%;
display: inline-block;
}
.repo-admin .repo-access-state {
text-align: center;
width: 520px;
}
.repo-admin .repo-access-state .state-icon i.icon-lock {
background: rgb(253, 191, 191);
}
.repo-admin .repo-access-state .state-icon i.icon-unlock-alt {
background: rgb(170, 236, 170);
}
.repo-admin .change-access {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #eee;
text-align: center;
}
.repo-admin .change-access .alert {
color: black;
background: white;
border: 1px solid transparent;
}
.repo-admin .change-access .alert .alert-content {
opacity: 0;
}
.repo-admin .change-access:hover .alert {
background: inherit;
border: inherit;
}
/* Overrides for typeahead to work with bootstrap 3. */
.twitter-typeahead .tt-query,

View file

@ -212,17 +212,36 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
});
};
$scope.askChangeAccess = function(newAccess) {
$('#make' + newAccess + 'Modal').modal({});
};
$scope.changeAccess = function(newAccess) {
$('#make' + newAccess + 'Modal').modal('hide');
var visibility = {
'visibility': newAccess
};
var visibilityPost = Restangular.one('repository/' + namespace + '/' + name + '/changevisibility');
visibilityPost.customPOST(visibility).then(function() {
$scope.repo.is_public = newAccess == 'public';
}, function() {
$('#cannotchangeModal').modal({});
});
};
// Fetch the repository information.
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
repositoryFetch.get().then(function(repo) {
$scope.repo = repo;
});
// Fetch the permissions.
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions');
permissionsFetch.get().then(function(resp) {
$rootScope.title = 'Settings - ' + namespace + '/' + name;
$scope.repo = {
'namespace': namespace,
'name': name
};
$scope.permissions = resp.permissions;
}, function() {
$scope.repo = null;
$scope.permissions = null;
$rootScope.title = 'Unknown Repository';
});

View file

@ -9,9 +9,10 @@
<i class="icon-hdd icon-large"></i> <span style="color: #aaa;"> {{repo.namespace}}</span> <span style="color: #ccc">/</span> {{repo.name}}
</h3>
</div>
<!-- User Access Permissions -->
<div class="panel panel-default">
<div class="panel-heading">Access Permissions</div>
<div class="panel-heading">User Access Permissions</div>
<div class="panel-body">
<table class="permissions">
@ -51,6 +52,33 @@
</table>
</div>
</div>
<br>
<!-- Public/Private -->
<div class="panel panel-default">
<div class="panel-heading">Repository Settings</div>
<div class="panel-body">
<div class="repo-access-state" ng-show="!repo.is_public">
<div class="state-icon"><i class="icon-lock"></i></div>
This repository is currently <b>private</b>. Only users on the above access list may interact with it.
<div class="change-access">
<button class="btn btn-danger" ng-click="askChangeAccess('public')">Make Public</button>
</div>
</div>
<div class="repo-access-state" ng-show="repo.is_public">
<div class="state-icon"><i class="icon-unlock-alt"></i></div>
This repository is currently <b>public</b> and visible to all users.
<div class="change-access">
<button class="btn btn-success" ng-click="askChangeAccess('private')">Make Private</button>
</div>
</div>
</div>
</div>
<!-- Modal message dialog -->
<div class="modal fade" id="cannotchangeModal">
@ -71,6 +99,52 @@
</div><!-- /.modal -->
<!-- Modal message dialog -->
<div class="modal fade" id="makepublicModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Make Repository Public</h4>
</div>
<div class="modal-body">
<div class="alert alert-warning">
Warning: This will allow <b>anyone</b> to pull from this repository
</div>
Are you sure you want to make this repository public?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" ng-click="changeAccess('public')">Make Public</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal message dialog -->
<div class="modal fade" id="makeprivateModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Make Repository Private</h4>
</div>
<div class="modal-body">
<div class="alert alert-warning">
Warning: Only users on the permissions list will be able to access this repository.
</div>
Are you sure you want to make this repository private?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" ng-click="changeAccess('private')">Make Private</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal message dialog -->
<div class="modal fade" id="onlyadminModal">
<div class="modal-dialog">

View file

@ -6,7 +6,12 @@
<!-- Repo Header -->
<div class="header">
<h3>
<i class="icon-hdd icon-large"></i> <span style="color: #aaa;"> {{repo.namespace}}</span> <span style="color: #ccc">/</span> {{repo.name}}
<span class="icon-container">
<i class="icon-lock icon-large" ng-show="!repo.is_public" title="Private Repository"></i>
<i class="icon-hdd icon-large"></i>
</span>
<span style="color: #aaa;"> {{repo.namespace}}</span> <span style="color: #ccc">/</span> {{repo.name}}
<span class="settings-cog" ng-show="repo.can_admin" title="Repository Settings">
<a href="{{ '#/repository/' + repo.namespace + '/' + repo.name + '/admin' }}">