mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
feat(uac): add multi user management and UAC (#647)
This commit is contained in:
parent
f28f223624
commit
80d50378c5
91 changed files with 3973 additions and 866 deletions
|
@ -58,6 +58,13 @@
|
|||
<span ng-show="sortType == 'Mode' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th ng-if="applicationState.application.authentication">
|
||||
<a ui-sref="containers" ng-click="order('Metadata.ResourceControl.OwnerId')">
|
||||
Ownership
|
||||
<span ng-show="sortType == 'Metadata.ResourceControl.OwnerId' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
||||
<span ng-show="sortType == 'Metadata.ResourceControl.OwnerId' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr dir-paginate="service in (state.filteredServices = ( services | filter:state.filter | orderBy:sortType:sortReverse | itemsPerPage: state.pagination_count))">
|
||||
|
@ -76,12 +83,33 @@
|
|||
<a class="interactive" ng-click="scaleService(service)"><i class="fa fa-check-square-o"></i></a>
|
||||
</span>
|
||||
</td>
|
||||
<td ng-if="applicationState.application.authentication">
|
||||
<span ng-if="user.role === 1 && service.Metadata.ResourceControl">
|
||||
<i class="fa fa-eye-slash" aria-hidden="true"></i>
|
||||
<span ng-if="service.Metadata.ResourceControl.OwnerId === user.ID">
|
||||
Private
|
||||
</span>
|
||||
<span ng-if="service.Metadata.ResourceControl.OwnerId !== user.ID">
|
||||
Private <span ng-if="service.Owner">(owner: {{ service.Owner }})</span>
|
||||
</span>
|
||||
<a ng-click="switchOwnership(service)" class="interactive"><i class="fa fa-eye" aria-hidden="true" style="margin-left: 7px;"></i> Switch to public</a>
|
||||
</span>
|
||||
<span ng-if="user.role !== 1 && service.Metadata.ResourceControl.OwnerId === user.ID">
|
||||
<i class="fa fa-eye-slash" aria-hidden="true"></i>
|
||||
Private
|
||||
<a ng-click="switchOwnership(service)" class="interactive"><i class="fa fa-eye" aria-hidden="true" style="margin-left: 7px;"></i> Switch to public</a>
|
||||
</span>
|
||||
<span ng-if="!service.Metadata.ResourceControl">
|
||||
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||
Public
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="!services">
|
||||
<td colspan="4" class="text-center text-muted">Loading...</td>
|
||||
<td colspan="5" class="text-center text-muted">Loading...</td>
|
||||
</tr>
|
||||
<tr ng-if="services.length == 0">
|
||||
<td colspan="4" class="text-center text-muted">No services available.</td>
|
||||
<td colspan="5" class="text-center text-muted">No services available.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,12 +1,40 @@
|
|||
angular.module('services', [])
|
||||
.controller('ServicesController', ['$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Messages', 'Pagination',
|
||||
function ($scope, $stateParams, $state, Service, ServiceHelper, Messages, Pagination) {
|
||||
.controller('ServicesController', ['$q', '$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Messages', 'Pagination', 'Authentication', 'UserService', 'ModalService', 'ResourceControlService',
|
||||
function ($q, $scope, $stateParams, $state, Service, ServiceHelper, Messages, Pagination, Authentication, UserService, ModalService, ResourceControlService) {
|
||||
$scope.state = {};
|
||||
$scope.state.selectedItemCount = 0;
|
||||
$scope.state.pagination_count = Pagination.getPaginationCount('services');
|
||||
$scope.sortType = 'Name';
|
||||
$scope.sortReverse = false;
|
||||
|
||||
function removeServiceResourceControl(service) {
|
||||
volumeResourceControlQueries = [];
|
||||
angular.forEach(service.Mounts, function (mount) {
|
||||
if (mount.Type === 'volume') {
|
||||
volumeResourceControlQueries.push(ResourceControlService.removeVolumeResourceControl(service.Metadata.ResourceControl.OwnerId, mount.Source));
|
||||
}
|
||||
});
|
||||
|
||||
$q.all(volumeResourceControlQueries)
|
||||
.then(function success() {
|
||||
return ResourceControlService.removeServiceResourceControl(service.Metadata.ResourceControl.OwnerId, service.Id);
|
||||
})
|
||||
.then(function success() {
|
||||
delete service.Metadata.ResourceControl;
|
||||
Messages.send('Ownership changed to public', service.Id);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Messages.error("Failure", err, "Unable to change service ownership");
|
||||
});
|
||||
}
|
||||
|
||||
$scope.switchOwnership = function(volume) {
|
||||
ModalService.confirmServiceOwnershipChange(function (confirmed) {
|
||||
if(!confirmed) { return; }
|
||||
removeServiceResourceControl(volume);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.changePaginationCount = function() {
|
||||
Pagination.setPaginationCount('services', $scope.state.pagination_count);
|
||||
};
|
||||
|
@ -57,9 +85,21 @@ function ($scope, $stateParams, $state, Service, ServiceHelper, Messages, Pagina
|
|||
$('#loadServicesSpinner').hide();
|
||||
Messages.error("Unable to remove service", {}, d[0].message);
|
||||
} else {
|
||||
Messages.send("Service deleted", service.Id);
|
||||
var index = $scope.services.indexOf(service);
|
||||
$scope.services.splice(index, 1);
|
||||
if (service.Metadata && service.Metadata.ResourceControl) {
|
||||
ResourceControlService.removeServiceResourceControl(service.Metadata.ResourceControl.OwnerId, service.Id)
|
||||
.then(function success() {
|
||||
Messages.send("Service deleted", service.Id);
|
||||
var index = $scope.services.indexOf(service);
|
||||
$scope.services.splice(index, 1);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Messages.error("Failure", err, "Unable to remove service ownership");
|
||||
});
|
||||
} else {
|
||||
Messages.send("Service deleted", service.Id);
|
||||
var index = $scope.services.indexOf(service);
|
||||
$scope.services.splice(index, 1);
|
||||
}
|
||||
}
|
||||
complete();
|
||||
}, function (e) {
|
||||
|
@ -70,12 +110,42 @@ function ($scope, $stateParams, $state, Service, ServiceHelper, Messages, Pagina
|
|||
});
|
||||
};
|
||||
|
||||
function mapUsersToServices(users) {
|
||||
angular.forEach($scope.services, function (service) {
|
||||
if (service.Metadata) {
|
||||
var serviceRC = service.Metadata.ResourceControl;
|
||||
if (serviceRC && serviceRC.OwnerId != $scope.user.ID) {
|
||||
angular.forEach(users, function (user) {
|
||||
if (serviceRC.OwnerId === user.Id) {
|
||||
service.Owner = user.Username;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchServices() {
|
||||
$('#loadServicesSpinner').show();
|
||||
var userDetails = Authentication.getUserDetails();
|
||||
$scope.user = userDetails;
|
||||
|
||||
Service.query({}, function (d) {
|
||||
$scope.services = d.map(function (service) {
|
||||
return new ServiceViewModel(service);
|
||||
});
|
||||
if (userDetails.role === 1) {
|
||||
UserService.users()
|
||||
.then(function success(data) {
|
||||
mapUsersToServices(data);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Messages.error("Failure", err, "Unable to retrieve users");
|
||||
})
|
||||
.finally(function final() {
|
||||
$('#loadServicesSpinner').hide();
|
||||
});
|
||||
}
|
||||
$('#loadServicesSpinner').hide();
|
||||
}, function(e) {
|
||||
$('#loadServicesSpinner').hide();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue