405 lines
12 KiB
JavaScript
405 lines
12 KiB
JavaScript
|
(function() {
|
||
|
/**
|
||
|
* Repository admin/settings page.
|
||
|
*/
|
||
|
angular.module('quayPages').config(['pages', function(pages) {
|
||
|
pages.create('repo-admin', 'repo-admin.html', RepoAdminCtrl);
|
||
|
}]);
|
||
|
|
||
|
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerService, $routeParams,
|
||
|
$rootScope, $location, UserService, Config, Features, ExternalNotificationData, UtilService) {
|
||
|
|
||
|
var namespace = $routeParams.namespace;
|
||
|
var name = $routeParams.name;
|
||
|
|
||
|
$scope.Features = Features;
|
||
|
$scope.TriggerService = TriggerService;
|
||
|
$scope.KeyService = KeyService;
|
||
|
|
||
|
$scope.permissions = {'team': [], 'user': [], 'loading': 2};
|
||
|
$scope.logsShown = 0;
|
||
|
$scope.deleting = false;
|
||
|
|
||
|
$scope.permissionCache = {};
|
||
|
$scope.showTriggerSetupCounter = 0;
|
||
|
|
||
|
$scope.getBadgeFormat = function(format, repo) {
|
||
|
if (!repo) { return; }
|
||
|
|
||
|
var imageUrl = Config.getUrl('/repository/' + namespace + '/' + name + '/status');
|
||
|
if (!$scope.repo.is_public) {
|
||
|
imageUrl += '?token=' + $scope.repo.status_token;
|
||
|
}
|
||
|
|
||
|
var linkUrl = Config.getUrl('/repository/' + namespace + '/' + name);
|
||
|
|
||
|
switch (format) {
|
||
|
case 'svg':
|
||
|
return imageUrl;
|
||
|
|
||
|
case 'md':
|
||
|
return '[![Docker Repository on ' + Config.REGISTRY_TITLE_SHORT + '](' + imageUrl +
|
||
|
' "Docker Repository on ' + Config.REGISTRY_TITLE_SHORT + '")](' + linkUrl + ')';
|
||
|
|
||
|
case 'asciidoc':
|
||
|
return 'image:' + imageUrl + '["Docker Repository on ' + Config.REGISTRY_TITLE_SHORT + '", link="' + linkUrl + '"]';
|
||
|
}
|
||
|
|
||
|
return '';
|
||
|
};
|
||
|
|
||
|
$scope.buildEntityForPermission = function(name, permission, kind) {
|
||
|
var key = name + ':' + kind;
|
||
|
if ($scope.permissionCache[key]) {
|
||
|
return $scope.permissionCache[key];
|
||
|
}
|
||
|
|
||
|
return $scope.permissionCache[key] = {
|
||
|
'kind': kind,
|
||
|
'name': name,
|
||
|
'is_robot': permission.is_robot,
|
||
|
'is_org_member': permission.is_org_member
|
||
|
};
|
||
|
};
|
||
|
|
||
|
$scope.loadLogs = function() {
|
||
|
$scope.logsShown++;
|
||
|
};
|
||
|
|
||
|
$scope.grantRole = function() {
|
||
|
$('#confirmaddoutsideModal').modal('hide');
|
||
|
var entity = $scope.currentAddEntity;
|
||
|
$scope.addRole(entity.name, 'read', entity.kind, entity.is_org_member)
|
||
|
$scope.currentAddEntity = null;
|
||
|
};
|
||
|
|
||
|
$scope.addNewPermission = function(entity) {
|
||
|
// Don't allow duplicates.
|
||
|
if (!entity || !entity.kind || $scope.permissions[entity.kind][entity.name]) { return; }
|
||
|
|
||
|
if (entity.is_org_member === false) {
|
||
|
$scope.currentAddEntity = entity;
|
||
|
$('#confirmaddoutsideModal').modal('show');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$scope.addRole(entity.name, 'read', entity.kind);
|
||
|
};
|
||
|
|
||
|
$scope.deleteRole = function(entityName, kind) {
|
||
|
var errorHandler = ApiService.errorDisplay('Cannot change permission', function(resp) {
|
||
|
if (resp.status == 409) {
|
||
|
return 'Cannot change permission as you do not have the authority';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var permissionDelete = Restangular.one(UtilService.getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||
|
permissionDelete.customDELETE().then(function() {
|
||
|
delete $scope.permissions[kind][entityName];
|
||
|
}, errorHandler);
|
||
|
};
|
||
|
|
||
|
$scope.addRole = function(entityName, role, kind) {
|
||
|
var permission = {
|
||
|
'role': role,
|
||
|
};
|
||
|
|
||
|
var permissionPost = Restangular.one(UtilService.getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||
|
permissionPost.customPUT(permission).then(function(result) {
|
||
|
$scope.permissions[kind][entityName] = result;
|
||
|
}, ApiService.errorDisplay('Cannot change permission'));
|
||
|
};
|
||
|
|
||
|
$scope.roles = [
|
||
|
{ 'id': 'read', 'title': 'Read', 'kind': 'success' },
|
||
|
{ 'id': 'write', 'title': 'Write', 'kind': 'success' },
|
||
|
{ 'id': 'admin', 'title': 'Admin', 'kind': 'primary' }
|
||
|
];
|
||
|
|
||
|
$scope.setRole = function(role, entityName, kind) {
|
||
|
var permission = $scope.permissions[kind][entityName];
|
||
|
var currentRole = permission.role;
|
||
|
permission.role = role;
|
||
|
|
||
|
var permissionPut = Restangular.one(UtilService.getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||
|
permissionPut.customPUT(permission).then(function() {}, function(resp) {
|
||
|
$scope.permissions[kind][entityName] = {'role': currentRole};
|
||
|
$scope.changePermError = null;
|
||
|
if (resp.status == 409 || resp.data) {
|
||
|
$scope.changePermError = resp.data || '';
|
||
|
$('#channgechangepermModal').modal({});
|
||
|
} else {
|
||
|
$('#cannotchangeModal').modal({});
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.newTokenName = null;
|
||
|
|
||
|
$scope.createToken = function() {
|
||
|
var data = {
|
||
|
'friendlyName': $scope.newTokenName
|
||
|
};
|
||
|
|
||
|
var params = {'repository': namespace + '/' + name};
|
||
|
ApiService.createToken(data, params).then(function(newToken) {
|
||
|
$scope.newTokenName = null;
|
||
|
$scope.createTokenForm.$setPristine();
|
||
|
$scope.tokens[newToken.code] = newToken;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.deleteToken = function(tokenCode) {
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name,
|
||
|
'code': tokenCode
|
||
|
};
|
||
|
|
||
|
ApiService.deleteToken(null, params).then(function() {
|
||
|
delete $scope.tokens[tokenCode];
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.changeTokenAccess = function(tokenCode, newAccess) {
|
||
|
var role = {
|
||
|
'role': newAccess
|
||
|
};
|
||
|
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name,
|
||
|
'code': tokenCode
|
||
|
};
|
||
|
|
||
|
ApiService.changeToken(role, params).then(function(updated) {
|
||
|
$scope.tokens[updated.code] = updated;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.shownTokenCounter = 0;
|
||
|
|
||
|
$scope.showToken = function(tokenCode) {
|
||
|
$scope.shownToken = $scope.tokens[tokenCode];
|
||
|
$scope.shownTokenCounter++;
|
||
|
};
|
||
|
|
||
|
$scope.askChangeAccess = function(newAccess) {
|
||
|
$('#make' + newAccess + 'Modal').modal({});
|
||
|
};
|
||
|
|
||
|
$scope.changeAccess = function(newAccess) {
|
||
|
$('#make' + newAccess + 'Modal').modal('hide');
|
||
|
|
||
|
var visibility = {
|
||
|
'visibility': newAccess
|
||
|
};
|
||
|
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name
|
||
|
};
|
||
|
|
||
|
ApiService.changeRepoVisibility(visibility, params).then(function() {
|
||
|
$scope.repo.is_public = newAccess == 'public';
|
||
|
}, function() {
|
||
|
$('#cannotchangeModal').modal({});
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.askDelete = function() {
|
||
|
$('#confirmdeleteModal').modal({});
|
||
|
};
|
||
|
|
||
|
$scope.deleteRepo = function() {
|
||
|
$('#confirmdeleteModal').modal('hide');
|
||
|
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name
|
||
|
};
|
||
|
|
||
|
$scope.deleting = true;
|
||
|
ApiService.deleteRepository(null, params).then(function() {
|
||
|
$scope.repo = null;
|
||
|
|
||
|
setTimeout(function() {
|
||
|
document.location = '/repository/';
|
||
|
}, 1000);
|
||
|
}, function() {
|
||
|
$scope.deleting = true;
|
||
|
$('#cannotchangeModal').modal({});
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.showNewNotificationCounter = 0;
|
||
|
|
||
|
$scope.showNewNotificationDialog = function() {
|
||
|
$scope.showNewNotificationCounter++;
|
||
|
};
|
||
|
|
||
|
$scope.handleNotificationCreated = function(notification) {
|
||
|
$scope.notifications.push(notification);
|
||
|
};
|
||
|
|
||
|
$scope.handleNotificationDeleted = function(notification) {
|
||
|
var index = $.inArray(notification, $scope.notifications);
|
||
|
if (index < 0) { return; }
|
||
|
$scope.notifications.splice(index, 1);
|
||
|
};
|
||
|
|
||
|
$scope.loadNotifications = function() {
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name
|
||
|
};
|
||
|
|
||
|
$scope.notificationsResource = ApiService.listRepoNotificationsAsResource(params).get(
|
||
|
function(resp) {
|
||
|
$scope.notifications = resp.notifications;
|
||
|
return $scope.notifications;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.showBuild = function(buildInfo) {
|
||
|
$location.path('/repository/' + namespace + '/' + name + '/build');
|
||
|
$location.search('current', buildInfo.id);
|
||
|
};
|
||
|
|
||
|
$scope.loadTriggerBuildHistory = function(trigger) {
|
||
|
trigger.$loadingHistory = true;
|
||
|
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name,
|
||
|
'trigger_uuid': trigger.id,
|
||
|
'limit': 3
|
||
|
};
|
||
|
|
||
|
ApiService.listTriggerRecentBuilds(null, params).then(function(resp) {
|
||
|
trigger.$builds = resp['builds'];
|
||
|
trigger.$loadingHistory = false;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.loadTriggers = function() {
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name
|
||
|
};
|
||
|
|
||
|
$scope.triggersResource = ApiService.listBuildTriggersAsResource(params).get(function(resp) {
|
||
|
$scope.triggers = resp.triggers;
|
||
|
|
||
|
// Check to see if we need to setup any trigger.
|
||
|
var newTriggerId = $routeParams.new_trigger;
|
||
|
if (newTriggerId) {
|
||
|
for (var i = 0; i < $scope.triggers.length; ++i) {
|
||
|
var trigger = $scope.triggers[i];
|
||
|
if (trigger['id'] == newTriggerId && !trigger['is_active']) {
|
||
|
$scope.setupTrigger(trigger);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $scope.triggers;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$scope.setupTrigger = function(trigger) {
|
||
|
$scope.currentSetupTrigger = trigger;
|
||
|
$scope.showTriggerSetupCounter++;
|
||
|
};
|
||
|
|
||
|
$scope.cancelSetupTrigger = function(trigger) {
|
||
|
if ($scope.currentSetupTrigger != trigger) { return; }
|
||
|
|
||
|
$scope.currentSetupTrigger = null;
|
||
|
$scope.deleteTrigger(trigger);
|
||
|
};
|
||
|
|
||
|
$scope.showManualBuildDialog = 0;
|
||
|
|
||
|
$scope.startTrigger = function(trigger, opt_custom) {
|
||
|
var parameters = TriggerService.getRunParameters(trigger.service);
|
||
|
if (parameters.length && !opt_custom) {
|
||
|
$scope.currentStartTrigger = trigger;
|
||
|
$scope.showManualBuildDialog++;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name,
|
||
|
'trigger_uuid': trigger.id
|
||
|
};
|
||
|
|
||
|
ApiService.manuallyStartBuildTrigger(opt_custom || {}, params).then(function(resp) {
|
||
|
var url = '/repository/' + namespace + '/' + name + '/build?current=' + resp['id'];
|
||
|
document.location = url;
|
||
|
}, ApiService.errorDisplay('Could not start build'));
|
||
|
};
|
||
|
|
||
|
$scope.deleteTrigger = function(trigger) {
|
||
|
if (!trigger) { return; }
|
||
|
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name,
|
||
|
'trigger_uuid': trigger.id
|
||
|
};
|
||
|
|
||
|
ApiService.deleteBuildTrigger(null, params).then(function(resp) {
|
||
|
$scope.triggers.splice($scope.triggers.indexOf(trigger), 1);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var fetchTokens = function() {
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name
|
||
|
};
|
||
|
|
||
|
ApiService.listRepoTokens(null, params).then(function(resp) {
|
||
|
$scope.tokens = resp.tokens;
|
||
|
}, function() {
|
||
|
$scope.tokens = null;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var fetchPermissions = function(kind) {
|
||
|
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/');
|
||
|
permissionsFetch.get().then(function(resp) {
|
||
|
$scope.permissions[kind] = resp.permissions;
|
||
|
$scope.permissions['loading']--;
|
||
|
}, function() {
|
||
|
$scope.permissions[kind] = null;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var fetchRepository = function() {
|
||
|
var params = {
|
||
|
'repository': namespace + '/' + name
|
||
|
};
|
||
|
|
||
|
$scope.repository = ApiService.getRepoAsResource(params).get(function(repo) {
|
||
|
if (!repo.can_admin) {
|
||
|
$rootScope.title = 'Forbidden';
|
||
|
$scope.accessDenied = true;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$scope.repo = repo;
|
||
|
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||
|
$rootScope.description = 'Administrator settings for ' + namespace + '/' + name +
|
||
|
': Permissions, notifications and other settings';
|
||
|
|
||
|
// Fetch all the permissions and token info for the repository.
|
||
|
fetchPermissions('user');
|
||
|
fetchPermissions('team');
|
||
|
fetchTokens();
|
||
|
|
||
|
$('.info-icon').popover({
|
||
|
'trigger': 'hover',
|
||
|
'html': true
|
||
|
});
|
||
|
|
||
|
return $scope.repo;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
// Fetch the repository.
|
||
|
fetchRepository();
|
||
|
}
|
||
|
})();
|