mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-19 01:35:28 +01:00
Add get/delete functions for api keys
This commit is contained in:
parent
2f69464e7a
commit
a6b7b84b3b
@ -96,6 +96,11 @@ def api_handlers(handler_args):
|
||||
ApiUsersUserKeyHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/users/([0-9]+)/key/([0-9]+)/?",
|
||||
ApiUsersUserKeyHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/users/([0-9]+)/?",
|
||||
ApiUsersUserIndexHandler,
|
||||
|
@ -9,7 +9,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ApiUsersUserKeyHandler(BaseApiHandler):
|
||||
def get(self, _user_id: str, key_id: int):
|
||||
def get(self, user_id: str, key_id=None):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
@ -20,38 +20,72 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
||||
_,
|
||||
_user,
|
||||
) = auth_data
|
||||
if key_id:
|
||||
key = self.controller.users.get_user_api_key(key_id)
|
||||
# does this user id exist?
|
||||
if key is None:
|
||||
self.redirect("/panel/error?error=Invalid Key ID")
|
||||
return
|
||||
|
||||
key = self.controller.users.get_user_api_key(key_id)
|
||||
# does this user id exist?
|
||||
if key is None:
|
||||
self.redirect("/panel/error?error=Invalid Key ID")
|
||||
return
|
||||
if (
|
||||
str(key.user_id) != str(auth_data[4]["user_id"])
|
||||
and not auth_data[4]["superuser"]
|
||||
):
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT AUTHORIZED",
|
||||
"error_data": "TRIED TO EDIT KEY WIHTOUT AUTH",
|
||||
},
|
||||
)
|
||||
|
||||
if (
|
||||
str(key.user_id) != str(auth_data[4]["user_id"])
|
||||
and not auth_data[4]["superuser"]
|
||||
):
|
||||
self.redirect(
|
||||
"/panel/error?error=You are not authorized to access this key."
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
f"Generated a new API token for the key {key.name} "
|
||||
f"from user with UID: {key.user_id}",
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
data_key = self.controller.authentication.generate(
|
||||
key.user_id_id, {"token_id": key.token_id}
|
||||
)
|
||||
return
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
f"Generated a new API token for the key {key.name} "
|
||||
f"from user with UID: {key.user_id}",
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
{
|
||||
"status": "ok",
|
||||
"data": self.controller.authentication.generate(
|
||||
key.user_id_id, {"token_id": key.token_id}
|
||||
),
|
||||
}
|
||||
)
|
||||
return self.finish_json(
|
||||
200,
|
||||
{"status": "ok", "data": data_key},
|
||||
)
|
||||
else:
|
||||
if (
|
||||
str(user_id) != str(auth_data[4]["user_id"])
|
||||
and not auth_data[4]["superuser"]
|
||||
):
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT AUTHORIZED",
|
||||
"error_data": "TRIED TO EDIT KEY WIHTOUT AUTH",
|
||||
},
|
||||
)
|
||||
keys = []
|
||||
for key in self.controller.users.get_user_api_keys(str(user_id)):
|
||||
keys.append(
|
||||
{
|
||||
"id": key.token_id,
|
||||
"name": key.name,
|
||||
"server_permissions": key.server_permissions,
|
||||
"crafty_permissions": key.crafty_permissions,
|
||||
"superuser": key.superuser,
|
||||
}
|
||||
)
|
||||
self.finish_json(
|
||||
200,
|
||||
{
|
||||
"status": "ok",
|
||||
"data": keys,
|
||||
},
|
||||
)
|
||||
|
||||
def patch(self, user_id: str):
|
||||
user_key_schema = {
|
||||
@ -144,3 +178,61 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
self.finish_json(200, {"status": "ok", "data": {"id": key_id}})
|
||||
|
||||
def delete(self, _user_id: str, key_id: str):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
(
|
||||
_,
|
||||
_exec_user_crafty_permissions,
|
||||
_,
|
||||
_,
|
||||
_user,
|
||||
) = auth_data
|
||||
if key_id:
|
||||
key = self.controller.users.get_user_api_key(key_id)
|
||||
# does this user id exist?
|
||||
if key is None:
|
||||
self.redirect("/panel/error?error=Invalid Key ID")
|
||||
return
|
||||
|
||||
# does this user id exist?
|
||||
target_key = self.controller.users.get_user_api_key(key_id)
|
||||
if not target_key:
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID KEY",
|
||||
"error_data": "INVALID KEY ID",
|
||||
},
|
||||
)
|
||||
|
||||
if (
|
||||
target_key.user_id != auth_data[4]["user_id"]
|
||||
and not auth_data[4]["superuser"]
|
||||
):
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT AUTHORIZED",
|
||||
"error_data": "TRIED TO EDIT KEY WIHTOUT AUTH",
|
||||
},
|
||||
)
|
||||
|
||||
self.controller.users.delete_user_api_key(key_id)
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
f"Removed API key {target_key} "
|
||||
f"(ID: {key_id}) from user {auth_data[4]['user_id']}",
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
|
||||
return self.finish_json(
|
||||
200,
|
||||
{"status": "ok", "data": {"id": key_id}},
|
||||
)
|
||||
|
@ -86,17 +86,14 @@
|
||||
apikey.server_permissions }}
|
||||
{{ translate('apiKeys', 'crafty', data['lang']) }} {{
|
||||
apikey.crafty_permissions }}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger delete-api-key"
|
||||
<td><button class="btn btn-danger delete-api-key"
|
||||
data-key-id="{{ apikey.token_id }}"
|
||||
data-key-name="{{ apikey.name }}">{{
|
||||
translate('panelConfig', 'delete', data['lang'])
|
||||
}}</button>
|
||||
data-key-name="{{ apikey.name }}">{{translate('panelConfig',
|
||||
'delete', data['lang'])}}</button>
|
||||
<button class="btn btn-outline-primary get-a-token"
|
||||
data-key-id="{{ apikey.token_id }}"
|
||||
data-key-name="{{ apikey.name }}">{{
|
||||
translate('apiKeys', 'getToken', data['lang']) }}
|
||||
</button>
|
||||
data-key-name="{{ apikey.name }}">{{translate('apiKeys',
|
||||
'getToken', data['lang'])}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% end %}
|
||||
@ -265,55 +262,56 @@
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log("ready!");
|
||||
$('.delete-api-key').click(function () {
|
||||
var keyId = $(this).data("key-id");
|
||||
var keyName = $(this).data("key-name");
|
||||
bootbox.confirm({
|
||||
title: `Remove API key ${keyName}?`,
|
||||
message: "Do you want to delete this API key? This cannot be undone.",
|
||||
buttons: {
|
||||
cancel: {
|
||||
label: '<i class="fas fa-times"></i> {{ translate("panelConfig", "cancel", data['lang']) }}'
|
||||
},
|
||||
confirm: {
|
||||
label: '<i class="fas fa-check"></i> {{ translate("serverBackups", "confirm", data['lang']) }}'
|
||||
}
|
||||
},
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
var token = getCookie("_xsrf")
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
headers: { 'X-XSRFToken': token },
|
||||
url: '/panel/remove_apikey?id=' + keyId,
|
||||
success: function (data) {
|
||||
location.reload();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
$('.get-a-token').click(function () {
|
||||
var keyId = $(this).data("key-id");
|
||||
var keyName = $(this).data("key-name");
|
||||
var token = getCookie("_xsrf")
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: { 'X-XSRFToken': token },
|
||||
url: '/panel/get_token?id=' + keyId,
|
||||
success: function (data) {
|
||||
bootbox.alert({
|
||||
title: `API token for ${keyName}`,
|
||||
message: `Here is an API token for ${keyName}:\n<pre style="white-space: pre-wrap;color:white;word-break:break-all;background: grey;border-radius: 5px;">${data}</pre>`
|
||||
});
|
||||
},
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
console.log("ready!");
|
||||
$('.delete-api-key').click(async function () {
|
||||
let keyId = $(this).data("key-id");
|
||||
let keyName = $(this).data("key-name");
|
||||
let token = getCookie("_xsrf");
|
||||
let res = await fetch(`/api/v2/users/${userId}/key/${keyId}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'X-XSRFToken': token
|
||||
},
|
||||
});
|
||||
let responseData = await res.json();
|
||||
if (responseData.status === "ok") {
|
||||
location.reload()
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
})
|
||||
$('.get-a-token').click(async function () {
|
||||
let keyId = $(this).data("key-id");
|
||||
let keyName = $(this).data("key-name");
|
||||
let token = getCookie("_xsrf");
|
||||
let res = await fetch(`/api/v2/users/${userId}/key/${keyId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-XSRFToken': token
|
||||
},
|
||||
});
|
||||
let responseData = await res.json();
|
||||
if (responseData.status === "ok") {
|
||||
bootbox.alert({
|
||||
title: `API token for ${keyName}`,
|
||||
message: `Here is an API token for ${keyName}:\n<pre style="white-space: pre-wrap;color:white;word-break:break-all;background: grey;border-radius: 5px;">${responseData.data}</pre>`
|
||||
});
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user