mirror of https://github.com/portainer/portainer
feat(users): prevent the removal of initial admin account (#3912)
* feat(users): prevent the removal of initial admin account * feat(users): disabled init admin delete buttonpull/3928/head
parent
381e372c4c
commit
24888fbbae
|
@ -1,6 +1,7 @@
|
||||||
package users
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
httperror "github.com/portainer/libhttp/error"
|
httperror "github.com/portainer/libhttp/error"
|
||||||
|
@ -17,6 +18,10 @@ func (handler *Handler) userDelete(w http.ResponseWriter, r *http.Request) *http
|
||||||
return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err}
|
return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if userID == 1 {
|
||||||
|
return &httperror.HandlerError{http.StatusForbidden, "Cannot remove the initial admin account", errors.New("Cannot remove the initial admin account")}
|
||||||
|
}
|
||||||
|
|
||||||
tokenData, err := security.RetrieveTokenData(r)
|
tokenData, err := security.RetrieveTokenData(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err}
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err}
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
>
|
>
|
||||||
<td>
|
<td>
|
||||||
<span class="md-checkbox">
|
<span class="md-checkbox">
|
||||||
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-click="$ctrl.selectItem(item, $event)" />
|
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-click="$ctrl.selectItem(item, $event)" ng-disabled="!$ctrl.allowSelection(item)" />
|
||||||
<label for="select_{{ $index }}"></label>
|
<label for="select_{{ $index }}"></label>
|
||||||
</span>
|
</span>
|
||||||
<a ui-sref="portainer.users.user({id: item.Id})">{{ item.Username }}</a>
|
<a ui-sref="portainer.users.user({id: item.Id})">{{ item.Username }}</a>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
import angular from 'angular';
|
||||||
|
import UsersDatatableController from './usersDatatableController';
|
||||||
|
|
||||||
angular.module('portainer.app').component('usersDatatable', {
|
angular.module('portainer.app').component('usersDatatable', {
|
||||||
templateUrl: './usersDatatable.html',
|
templateUrl: './usersDatatable.html',
|
||||||
controller: 'GenericDatatableController',
|
controller: UsersDatatableController,
|
||||||
bindings: {
|
bindings: {
|
||||||
titleText: '@',
|
titleText: '@',
|
||||||
titleIcon: '@',
|
titleIcon: '@',
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
export default class UsersDatatableController {
|
||||||
|
/* @ngInject*/
|
||||||
|
constructor($controller, $scope) {
|
||||||
|
const allowSelection = this.allowSelection;
|
||||||
|
angular.extend(this, $controller('GenericDatatableController', { $scope }));
|
||||||
|
this.allowSelection = allowSelection.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to allow/deny selection
|
||||||
|
*/
|
||||||
|
allowSelection(item) {
|
||||||
|
return item.Id !== 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,7 +34,9 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<button class="btn btn-primary btn-sm" ng-disabled="!isSubmitEnabled()" ng-click="updateUser()">Save</button>
|
<button class="btn btn-primary btn-sm" ng-disabled="!isSubmitEnabled()" ng-click="updateUser()">Save</button>
|
||||||
<button class="btn btn-danger btn-sm" ng-click="deleteUser()"><i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Delete this user</button>
|
<button class="btn btn-danger btn-sm" ng-disabled="isDeleteDisabled()" ng-click="deleteUser()"
|
||||||
|
><i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Delete this user</button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -91,6 +91,12 @@ angular.module('portainer.app').controller('UserController', [
|
||||||
return user && (user.Username !== formValues.username || (formValues.Administrator && user.Role !== 1) || (!formValues.Administrator && user.Role === 1));
|
return user && (user.Username !== formValues.username || (formValues.Administrator && user.Role !== 1) || (!formValues.Administrator && user.Role === 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.isDeleteDisabled = isDeleteDisabled;
|
||||||
|
function isDeleteDisabled() {
|
||||||
|
const { user } = $scope;
|
||||||
|
return user && user.Id === 1;
|
||||||
|
}
|
||||||
|
|
||||||
function initView() {
|
function initView() {
|
||||||
$scope.isAdmin = Authentication.isAdmin();
|
$scope.isAdmin = Authentication.isAdmin();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue