Merge pull request #660 from coreos-inc/superuser
Superuser Panel Improvements
This commit is contained in:
commit
4ae940aede
3 changed files with 80 additions and 5 deletions
|
@ -9,7 +9,7 @@ from flask import request
|
||||||
|
|
||||||
import features
|
import features
|
||||||
|
|
||||||
from app import app, avatar, superusers, authentication
|
from app import app, avatar, superusers, authentication, config_provider
|
||||||
from endpoints.api import (ApiResource, nickname, resource, validate_json_request,
|
from endpoints.api import (ApiResource, nickname, resource, validate_json_request,
|
||||||
internal_only, require_scope, show_if, parse_args,
|
internal_only, require_scope, show_if, parse_args,
|
||||||
query_param, abort, require_fresh_login, path_param, verify_not_prod)
|
query_param, abort, require_fresh_login, path_param, verify_not_prod)
|
||||||
|
@ -131,6 +131,7 @@ class SuperUserLogs(ApiResource):
|
||||||
def org_view(org):
|
def org_view(org):
|
||||||
return {
|
return {
|
||||||
'name': org.username,
|
'name': org.username,
|
||||||
|
'email': org.email,
|
||||||
'avatar': avatar.get_data_for_org(org),
|
'avatar': avatar.get_data_for_org(org),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +237,10 @@ class SuperUserList(ApiResource):
|
||||||
@require_scope(scopes.SUPERUSER)
|
@require_scope(scopes.SUPERUSER)
|
||||||
def post(self):
|
def post(self):
|
||||||
""" Creates a new user. """
|
""" Creates a new user. """
|
||||||
|
# Ensure that we are using database auth.
|
||||||
|
if app.config['AUTHENTICATION_TYPE'] != 'Database':
|
||||||
|
abort(400)
|
||||||
|
|
||||||
user_information = request.get_json()
|
user_information = request.get_json()
|
||||||
if SuperUserPermission().can():
|
if SuperUserPermission().can():
|
||||||
username = user_information['username']
|
username = user_information['username']
|
||||||
|
@ -274,6 +279,10 @@ class SuperUserSendRecoveryEmail(ApiResource):
|
||||||
@nickname('sendInstallUserRecoveryEmail')
|
@nickname('sendInstallUserRecoveryEmail')
|
||||||
@require_scope(scopes.SUPERUSER)
|
@require_scope(scopes.SUPERUSER)
|
||||||
def post(self, username):
|
def post(self, username):
|
||||||
|
# Ensure that we are using database auth.
|
||||||
|
if app.config['AUTHENTICATION_TYPE'] != 'Database':
|
||||||
|
abort(400)
|
||||||
|
|
||||||
if SuperUserPermission().can():
|
if SuperUserPermission().can():
|
||||||
user = model.user.get_nonrobot_user(username)
|
user = model.user.get_nonrobot_user(username)
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -370,9 +379,17 @@ class SuperUserManagement(ApiResource):
|
||||||
|
|
||||||
user_data = request.get_json()
|
user_data = request.get_json()
|
||||||
if 'password' in user_data:
|
if 'password' in user_data:
|
||||||
|
# Ensure that we are using database auth.
|
||||||
|
if app.config['AUTHENTICATION_TYPE'] != 'Database':
|
||||||
|
abort(400)
|
||||||
|
|
||||||
model.user.change_password(user, user_data['password'])
|
model.user.change_password(user, user_data['password'])
|
||||||
|
|
||||||
if 'email' in user_data:
|
if 'email' in user_data:
|
||||||
|
# Ensure that we are using database auth.
|
||||||
|
if app.config['AUTHENTICATION_TYPE'] != 'Database':
|
||||||
|
abort(400)
|
||||||
|
|
||||||
model.user.update_email(user, user_data['email'], auto_verify=True)
|
model.user.update_email(user, user_data['email'], auto_verify=True)
|
||||||
|
|
||||||
if 'enabled' in user_data:
|
if 'enabled' in user_data:
|
||||||
|
@ -380,6 +397,18 @@ class SuperUserManagement(ApiResource):
|
||||||
user.enabled = bool(user_data['enabled'])
|
user.enabled = bool(user_data['enabled'])
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
|
if 'superuser' in user_data:
|
||||||
|
config_object = config_provider.get_config()
|
||||||
|
superusers_set = set(config_object['SUPER_USERS'])
|
||||||
|
|
||||||
|
if user_data['superuser']:
|
||||||
|
superusers_set.add(username)
|
||||||
|
elif username in superusers_set:
|
||||||
|
superusers_set.remove(username)
|
||||||
|
|
||||||
|
config_object['SUPER_USERS'] = list(superusers_set)
|
||||||
|
config_provider.save_config(config_object)
|
||||||
|
|
||||||
return user_view(user, password=user_data.get('password'))
|
return user_view(user, password=user_data.get('password'))
|
||||||
|
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
|
@ -160,6 +160,31 @@
|
||||||
}, errorHandler)
|
}, errorHandler)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.setSuperuser = function(user, status) {
|
||||||
|
var setSuperuser = function() {
|
||||||
|
var params = {
|
||||||
|
'username': user.username
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
'superuser': status
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.changeInstallUser(data, params).then(function(resp) {
|
||||||
|
$scope.requiresRestart = true;
|
||||||
|
}, ApiService.errorDisplay('Could not change user'));
|
||||||
|
};
|
||||||
|
|
||||||
|
var msg = 'Note: This change, once applied, will require your installation ' +
|
||||||
|
'to be restarted to take effect';
|
||||||
|
|
||||||
|
bootbox.confirm(msg, function(status) {
|
||||||
|
if (status) {
|
||||||
|
setSuperuser();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$scope.showDeleteUser = function(user) {
|
$scope.showDeleteUser = function(user) {
|
||||||
if (user.username == UserService.currentUser().username) {
|
if (user.username == UserService.currentUser().username) {
|
||||||
bootbox.dialog({
|
bootbox.dialog({
|
||||||
|
|
|
@ -106,6 +106,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<td style="width: 24px;"></td>
|
<td style="width: 24px;"></td>
|
||||||
<td>Name</td>
|
<td>Name</td>
|
||||||
|
<td>Admin E-mail</td>
|
||||||
<td style="width: 24px;"></td>
|
<td style="width: 24px;"></td>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
@ -117,6 +118,9 @@
|
||||||
<td>
|
<td>
|
||||||
{{ current_org.name }}
|
{{ current_org.name }}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="mailto:{{ current_org.email }}">{{ current_org.email }}</a>
|
||||||
|
</td>
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center;">
|
||||||
<span class="cor-options-menu">
|
<span class="cor-options-menu">
|
||||||
<span class="cor-option" option-click="askRenameOrganization(current_org)">
|
<span class="cor-option" option-click="askRenameOrganization(current_org)">
|
||||||
|
@ -140,9 +144,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="users">
|
<div ng-show="users">
|
||||||
<div class="manager-header" header-title="Users">
|
<div class="manager-header" header-title="Users">
|
||||||
<button class="create-button btn btn-primary" ng-click="showCreateUser()">
|
<button class="create-button btn btn-primary" ng-click="showCreateUser()"
|
||||||
|
quay-show="Config.AUTHENTICATION_TYPE == 'Database'">
|
||||||
<i class="fa fa-plus" style="margin-right: 6px;"></i>Create User
|
<i class="fa fa-plus" style="margin-right: 6px;"></i>Create User
|
||||||
</button>
|
</button>
|
||||||
|
<span class="co-alert co-alert-info" quay-show="Config.AUTHENTICATION_TYPE != 'Database'">
|
||||||
|
Note: <span class="registry-name"></span> is configured to use external authentication, so users can only be created in that system
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="filter-box" collection="users" filter-model="search" filter-name="Users"></div>
|
<div class="filter-box" collection="users" filter-model="search" filter-name="Users"></div>
|
||||||
|
@ -177,14 +185,27 @@
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center;">
|
||||||
<span class="cor-options-menu"
|
<span class="cor-options-menu"
|
||||||
ng-if="user.username != current_user.username && !current_user.super_user">
|
ng-if="user.username != current_user.username && !current_user.super_user">
|
||||||
<span class="cor-option" option-click="showChangeEmail(current_user)">
|
<span class="cor-option" option-click="setSuperuser(current_user, true)"
|
||||||
|
quay-show="!current_user.super_user">
|
||||||
|
<i class="fa">Ω</i>
|
||||||
|
Make Superuser
|
||||||
|
</span>
|
||||||
|
<span class="cor-option" option-click="setSuperuser(current_user, false)"
|
||||||
|
quay-show="current_user.super_user">
|
||||||
|
<i class="fa">ω</i>
|
||||||
|
Remove Superuser
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="cor-option" option-click="showChangeEmail(current_user)"
|
||||||
|
quay-show="Config.AUTHENTICATION_TYPE == 'Database'">
|
||||||
<i class="fa fa-envelope-o"></i> Change E-mail Address
|
<i class="fa fa-envelope-o"></i> Change E-mail Address
|
||||||
</span>
|
</span>
|
||||||
<span class="cor-option" option-click="showChangePassword(current_user)">
|
<span class="cor-option" option-click="showChangePassword(current_user)"
|
||||||
|
quay-show="Config.AUTHENTICATION_TYPE == 'Database'">
|
||||||
<i class="fa fa-key"></i> Change Password
|
<i class="fa fa-key"></i> Change Password
|
||||||
</span>
|
</span>
|
||||||
<span class="cor-option" option-click="sendRecoveryEmail(current_user)"
|
<span class="cor-option" option-click="sendRecoveryEmail(current_user)"
|
||||||
quay-show="Features.MAILING">
|
quay-show="Features.MAILING && Config.AUTHENTICATION_TYPE == 'Database'">
|
||||||
<i class="fa fa-envelope"></i> Send Recovery E-mail
|
<i class="fa fa-envelope"></i> Send Recovery E-mail
|
||||||
</span>
|
</span>
|
||||||
<span class="cor-option" option-click="showDeleteUser(current_user)">
|
<span class="cor-option" option-click="showDeleteUser(current_user)">
|
||||||
|
|
Reference in a new issue