mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into bugfix/login-query
This commit is contained in:
commit
6257ea9c43
@ -5,7 +5,7 @@ yamllint:
|
||||
stage: lint
|
||||
image: registry.gitlab.com/pipeline-components/yamllint:latest
|
||||
tags:
|
||||
- docker
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
@ -18,7 +18,7 @@ jsonlint:
|
||||
stage: lint
|
||||
image: registry.gitlab.com/pipeline-components/jsonlint:latest
|
||||
tags:
|
||||
- docker
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
@ -33,7 +33,7 @@ black:
|
||||
stage: lint
|
||||
image: registry.gitlab.com/pipeline-components/black:latest
|
||||
tags:
|
||||
- docker
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
@ -46,7 +46,7 @@ pylint:
|
||||
stage: lint
|
||||
image: registry.gitlab.com/pipeline-components/pylint:latest
|
||||
tags:
|
||||
- docker
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
@ -69,7 +69,7 @@ sonarcloud-check:
|
||||
name: sonarsource/sonar-scanner-cli:latest
|
||||
entrypoint: [""]
|
||||
tags:
|
||||
- docker
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$SONAR_TOKEN == null"
|
||||
when: never
|
||||
@ -91,7 +91,7 @@ lang-check:
|
||||
stage: lint
|
||||
image: alpine:latest
|
||||
tags:
|
||||
- docker
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
|
@ -1,13 +1,15 @@
|
||||
# Changelog
|
||||
## --- [4.3.3] - 2024/TBD
|
||||
### Refactor
|
||||
- Refactor API keys "super user" to "full access" ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/731))
|
||||
### New features
|
||||
TBD
|
||||
### Bug fixes
|
||||
TBD
|
||||
### Tweaks
|
||||
TBD
|
||||
- Add link to go back to dashboard on error page ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/743))
|
||||
### Lang
|
||||
TBD
|
||||
- Changes of phrase in `cs_CS` translation ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/749))
|
||||
<br><br>
|
||||
|
||||
## --- [4.3.2] - 2024/04/07
|
||||
|
@ -17,6 +17,10 @@ class ServerPermsController:
|
||||
def get_server_user_list(server_id):
|
||||
return PermissionsServers.get_server_user_list(server_id)
|
||||
|
||||
@staticmethod
|
||||
def get_permissions(permissions_mask):
|
||||
return PermissionsServers.get_permissions(permissions_mask)
|
||||
|
||||
@staticmethod
|
||||
def list_defined_permissions():
|
||||
permissions_list = PermissionsServers.get_permissions_list()
|
||||
@ -61,6 +65,22 @@ class ServerPermsController:
|
||||
def get_permissions_mask(role_id, server_id):
|
||||
return PermissionsServers.get_permissions_mask(role_id, server_id)
|
||||
|
||||
@staticmethod
|
||||
def get_lowest_api_perm_mask(user_server_permissions_mask, api_key_permssions_mask):
|
||||
mask = ""
|
||||
# If this isn't an API key we'll know the request came from basic
|
||||
# authentication and ignore the API key permissions mask.
|
||||
if not api_key_permssions_mask:
|
||||
return user_server_permissions_mask
|
||||
for _index, (user_perm, api_perm) in enumerate(
|
||||
zip(user_server_permissions_mask, api_key_permssions_mask)
|
||||
):
|
||||
if user_perm == "1" and api_perm == "1":
|
||||
mask += "1"
|
||||
else:
|
||||
mask += "0"
|
||||
return mask
|
||||
|
||||
@staticmethod
|
||||
def set_permission(
|
||||
permission_mask, permission_tested: EnumPermissionsServer, value
|
||||
@ -82,6 +102,11 @@ class ServerPermsController:
|
||||
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
|
||||
return PermissionsServers.get_api_key_permissions_list(key, server_id)
|
||||
|
||||
@staticmethod
|
||||
def get_user_permissions_mask(user_id: str, server_id: str):
|
||||
user = HelperUsers.get_user_model(user_id)
|
||||
return PermissionsServers.get_user_permissions_mask(user, server_id)
|
||||
|
||||
@staticmethod
|
||||
def get_authorized_servers_stats_from_roles(user_id):
|
||||
user_roles = HelperUsers.get_user_roles_id(user_id)
|
||||
|
@ -187,7 +187,7 @@ class PermissionsCrafty:
|
||||
@staticmethod
|
||||
def get_api_key_permissions_list(key: ApiKeys):
|
||||
user = HelperUsers.get_user(key.user_id)
|
||||
if user["superuser"] and key.superuser:
|
||||
if user["superuser"] and key.full_access:
|
||||
return PermissionsCrafty.get_permissions_list()
|
||||
if user["superuser"]:
|
||||
# User is superuser but API key isn't
|
||||
|
@ -264,7 +264,7 @@ class PermissionsServers:
|
||||
@staticmethod
|
||||
def get_api_key_permissions_list(key: ApiKeys, server_id: str):
|
||||
user = HelperUsers.get_user(key.user_id)
|
||||
if user["superuser"] and key.superuser:
|
||||
if user["superuser"] and key.full_access:
|
||||
return PermissionsServers.get_permissions_list()
|
||||
roles_list = HelperUsers.get_user_roles_id(user["user_id"])
|
||||
role_server = (
|
||||
|
@ -71,7 +71,7 @@ class ApiKeys(BaseModel):
|
||||
user_id = ForeignKeyField(Users, backref="api_token", index=True)
|
||||
server_permissions = CharField(default="00000000")
|
||||
crafty_permissions = CharField(default="000")
|
||||
superuser = BooleanField(default=False)
|
||||
full_access = BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
table_name = "api_keys"
|
||||
@ -408,7 +408,7 @@ class HelperUsers:
|
||||
def add_user_api_key(
|
||||
name: str,
|
||||
user_id: str,
|
||||
superuser: bool = False,
|
||||
full_access: bool = False,
|
||||
server_permissions_mask: t.Optional[str] = None,
|
||||
crafty_permissions_mask: t.Optional[str] = None,
|
||||
):
|
||||
@ -426,7 +426,7 @@ class HelperUsers:
|
||||
if crafty_permissions_mask is not None
|
||||
else {}
|
||||
),
|
||||
ApiKeys.superuser: superuser,
|
||||
ApiKeys.full_access: full_access,
|
||||
}
|
||||
).execute()
|
||||
|
||||
|
@ -182,6 +182,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
t.List[str],
|
||||
bool,
|
||||
t.Dict[str, t.Any],
|
||||
str,
|
||||
]
|
||||
]:
|
||||
try:
|
||||
@ -190,9 +191,10 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
)
|
||||
|
||||
superuser = user["superuser"]
|
||||
server_permissions_api_mask = ""
|
||||
if api_key is not None:
|
||||
superuser = superuser and api_key.superuser
|
||||
|
||||
superuser = superuser and api_key.full_access
|
||||
server_permissions_api_mask = api_key.server_permissions
|
||||
exec_user_role = set()
|
||||
if superuser:
|
||||
authorized_servers = self.controller.servers.get_all_defined_servers()
|
||||
@ -214,6 +216,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
user["user_id"]
|
||||
)
|
||||
)
|
||||
|
||||
logger.debug(user["roles"])
|
||||
for r in user["roles"]:
|
||||
role = self.controller.roles.get_role(r)
|
||||
@ -234,6 +237,7 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
exec_user_role,
|
||||
superuser,
|
||||
user,
|
||||
server_permissions_api_mask,
|
||||
)
|
||||
logging.debug("Auth unsuccessful")
|
||||
auth_log.error(
|
||||
|
@ -168,7 +168,7 @@ class PanelHandler(BaseHandler):
|
||||
# Commented out because there is no server access control for API keys,
|
||||
# they just inherit from the host user
|
||||
# if api_key is not None:
|
||||
# superuser = superuser and api_key.superuser
|
||||
# superuser = superuser and api_key.full_access
|
||||
|
||||
if server_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
@ -242,7 +242,7 @@ class PanelHandler(BaseHandler):
|
||||
api_key, _token_data, exec_user = self.current_user
|
||||
superuser = exec_user["superuser"]
|
||||
if api_key is not None:
|
||||
superuser = superuser and api_key.superuser
|
||||
superuser = superuser and api_key.full_access
|
||||
|
||||
if superuser: # TODO: Figure out a better solution
|
||||
defined_servers = self.controller.servers.list_defined_servers()
|
||||
@ -351,7 +351,7 @@ class PanelHandler(BaseHandler):
|
||||
"created": api_key.created,
|
||||
"server_permissions": api_key.server_permissions,
|
||||
"crafty_permissions": api_key.crafty_permissions,
|
||||
"superuser": api_key.superuser,
|
||||
"full_access": api_key.full_access,
|
||||
}
|
||||
if api_key is not None
|
||||
else None
|
||||
@ -1356,6 +1356,9 @@ class PanelHandler(BaseHandler):
|
||||
page_data["crafty_permissions_all"] = (
|
||||
self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||
)
|
||||
page_data["user_crafty_permissions"] = (
|
||||
self.controller.crafty_perms.get_crafty_permissions_list(user_id)
|
||||
)
|
||||
|
||||
if user_id is None:
|
||||
self.redirect("/panel/error?error=Invalid User ID")
|
||||
|
@ -18,13 +18,14 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.COMMANDS
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.COMMANDS not in server_permissions:
|
||||
# if the user doesn't have Commands permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -26,12 +26,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.BACKUP
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
self.finish_json(200, self.controller.management.get_backup_config(server_id))
|
||||
@ -41,12 +43,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
backup_conf = self.controller.management.get_backup_config(server_id)
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.BACKUP
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
@ -89,12 +93,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.BACKUP
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -42,12 +42,14 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.BACKUP
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
self.finish_json(200, self.controller.management.get_backup_config(server_id))
|
||||
@ -82,13 +84,14 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.BACKUP
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -80,16 +80,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
and EnumPermissionsServer.BACKUP
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
EnumPermissionsServer.FILES not in server_permissions
|
||||
and EnumPermissionsServer.BACKUP not in server_permissions
|
||||
):
|
||||
# if the user doesn't have Files or Backup permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
@ -197,13 +197,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
try:
|
||||
@ -254,13 +255,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
try:
|
||||
@ -307,13 +309,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
try:
|
||||
@ -373,13 +376,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
try:
|
||||
@ -438,13 +442,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
try:
|
||||
@ -504,13 +509,14 @@ class ApiServersServerFilesZipHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.FILES
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
try:
|
||||
|
@ -102,13 +102,14 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Config permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
@ -154,13 +155,14 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Config permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -30,13 +30,14 @@ class ApiServersServerLogsHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.LOGS
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.LOGS not in server_permissions:
|
||||
# if the user doesn't have Logs permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -16,13 +16,14 @@ class ApiServersServerStdinHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.COMMANDS
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.COMMANDS not in server_permissions:
|
||||
# if the user doesn't have Commands permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -78,13 +78,14 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.SCHEDULE
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
data["server_id"] = server_id
|
||||
|
@ -54,12 +54,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.SCHEDULE
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
self.finish_json(200, self.controller.management.get_scheduled_task(task_id))
|
||||
@ -68,12 +70,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.SCHEDULE
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
@ -120,13 +124,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.SCHEDULE
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
|
@ -38,12 +38,14 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
self.finish_json(
|
||||
@ -81,13 +83,14 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
data["server_id"] = server_id
|
||||
|
@ -39,12 +39,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
if (
|
||||
@ -66,12 +68,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
auth_data = self.authenticate_user()
|
||||
if not auth_data:
|
||||
return
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
@ -117,13 +121,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
@ -159,13 +164,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
if (
|
||||
EnumPermissionsServer.CONFIG
|
||||
not in self.controller.server_perms.get_user_id_permissions_list(
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
)
|
||||
):
|
||||
),
|
||||
auth_data[5],
|
||||
)
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
webhook = self.controller.management.get_webhook_by_id(webhook_id)
|
||||
|
@ -75,7 +75,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
||||
"name": key.name,
|
||||
"server_permissions": key.server_permissions,
|
||||
"crafty_permissions": key.crafty_permissions,
|
||||
"superuser": key.superuser,
|
||||
"full_access": key.full_access,
|
||||
}
|
||||
)
|
||||
self.finish_json(
|
||||
@ -99,7 +99,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
||||
"type": "string",
|
||||
"pattern": "^[01]{3}$", # 8 bits, see EnumPermissionsCrafty
|
||||
},
|
||||
"superuser": {"type": "boolean"},
|
||||
"full_access": {"type": "boolean"},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -163,7 +163,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
|
||||
key_id = self.controller.users.add_user_api_key(
|
||||
data["name"],
|
||||
user_id,
|
||||
data["superuser"],
|
||||
data["full_access"],
|
||||
data["server_permissions_mask"],
|
||||
data["crafty_permissions_mask"],
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ class ServerHandler(BaseHandler):
|
||||
) = self.current_user
|
||||
superuser = exec_user["superuser"]
|
||||
if api_key is not None:
|
||||
superuser = superuser and api_key.superuser
|
||||
superuser = superuser and api_key.full_access
|
||||
|
||||
if superuser:
|
||||
defined_servers = self.controller.servers.list_defined_servers()
|
||||
@ -124,7 +124,7 @@ class ServerHandler(BaseHandler):
|
||||
"created": api_key.created,
|
||||
"server_permissions": api_key.server_permissions,
|
||||
"crafty_permissions": api_key.crafty_permissions,
|
||||
"superuser": api_key.superuser,
|
||||
"full_access": api_key.full_access,
|
||||
}
|
||||
if api_key is not None
|
||||
else None
|
||||
|
@ -42,7 +42,7 @@ class UploadHandler(BaseHandler):
|
||||
if self.upload_type == "server_import":
|
||||
superuser = exec_user["superuser"]
|
||||
if api_key is not None:
|
||||
superuser = superuser and api_key.superuser
|
||||
superuser = superuser and api_key.full_access
|
||||
user_id = exec_user["user_id"]
|
||||
stream_size_value = self.helper.get_setting("stream_size_GB")
|
||||
|
||||
@ -133,7 +133,7 @@ class UploadHandler(BaseHandler):
|
||||
elif self.upload_type == "background":
|
||||
superuser = exec_user["superuser"]
|
||||
if api_key is not None:
|
||||
superuser = superuser and api_key.superuser
|
||||
superuser = superuser and api_key.full_access
|
||||
user_id = exec_user["user_id"]
|
||||
stream_size_value = self.helper.get_setting("stream_size_GB")
|
||||
|
||||
@ -212,7 +212,7 @@ class UploadHandler(BaseHandler):
|
||||
server_id = self.get_argument("server_id", None)
|
||||
superuser = exec_user["superuser"]
|
||||
if api_key is not None:
|
||||
superuser = superuser and api_key.superuser
|
||||
superuser = superuser and api_key.full_access
|
||||
user_id = exec_user["user_id"]
|
||||
stream_size_value = self.helper.get_setting("stream_size_GB")
|
||||
|
||||
|
@ -58,7 +58,7 @@
|
||||
<!--<th>ID</th>-->
|
||||
<th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
|
||||
<th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
|
||||
<th>{{ translate('apiKeys', 'superUser', data['lang']) }}</th>
|
||||
<th>{{ translate('apiKeys', 'fullAccess', data['lang']) }}</th>
|
||||
<th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
|
||||
<th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
|
||||
</tr>
|
||||
@ -70,7 +70,7 @@
|
||||
<td>{{ apikey.name }}</td>
|
||||
<td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
|
||||
<td>
|
||||
{% if apikey.superuser %}
|
||||
{% if apikey.full_access %}
|
||||
<span class="text-success">
|
||||
<i class="fas fa-check-square"></i> {{
|
||||
translate('apiKeys', 'yes', data['lang']) }}
|
||||
@ -148,9 +148,15 @@
|
||||
}}</label>
|
||||
</td>
|
||||
<td>
|
||||
{% if permission in data['user_crafty_permissions'] %}
|
||||
<input type="checkbox" class="crafty_perm"
|
||||
id="permission_{{ permission.name }}"
|
||||
name="permission_{{ permission.name }}" value="1">
|
||||
{% else %}
|
||||
<input type="checkbox" class="crafty_perm"
|
||||
id="permission_{{ permission.name }}"
|
||||
name="permission_{{ permission.name }}" value="1" disabled>
|
||||
{% end %}
|
||||
</td>
|
||||
</tr>
|
||||
{% end %}
|
||||
@ -158,8 +164,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<label for="superuser">Superuser</label>
|
||||
<input type="checkbox" class="" id="superuser" name="superuser" value="1">
|
||||
<label for="full_access">{{translate('apiKeys', 'fullAccess', data['lang'])}}</label>
|
||||
<input type="checkbox" class="" id="full_access" name="full_access" value="1">
|
||||
|
||||
<br />
|
||||
|
||||
@ -240,7 +246,7 @@
|
||||
"name": formDataObject.name,
|
||||
"server_permissions_mask": server_permissions,
|
||||
"crafty_permissions_mask": crafty_permissions,
|
||||
"superuser": $("#superuser").prop('checked'),
|
||||
"full_access": $("#full_access").prop('checked'),
|
||||
});
|
||||
console.log(formDataJsonString);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="{{ data.get('lang_page', 'en') }}" class="{{data['user_data'].get('theme', 'default')}}"
|
||||
data-username="{{data['user_data'].get('username', None)}}">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
@ -60,6 +61,11 @@
|
||||
<b>{{ translate('error', 'hereIsTheError', data['lang']) }}: {{data['error']}}</b><br /><br />
|
||||
That's all the help I can give you - Godspeed
|
||||
<br /><br />
|
||||
<a class="d-inline font-weight-medium" href="/panel/dashboard"><button class="btn btn-info">{{
|
||||
translate('error', 'return',
|
||||
data['lang'])}}</button></a>
|
||||
<br>
|
||||
<br>
|
||||
<a class="d-inline font-weight-medium" href="https://discord.gg/9VJPhCE"> {{ translate('error',
|
||||
'contact', data['lang']) }}</a>
|
||||
</p>
|
||||
|
17
app/migrations/20240317_apikey_full_access.py
Normal file
17
app/migrations/20240317_apikey_full_access.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.rename_column("api_keys", "superuser", "full_access")
|
||||
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.rename_column("api_keys", "full_access", "superuser")
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
@ -20,6 +20,7 @@
|
||||
"created": "Vytvořen",
|
||||
"deleteKeyConfirmation": "Chcete tento API klíč odstranit? Tuto akci nelze vrátit zpět.",
|
||||
"deleteKeyConfirmationTitle": "Odstranit klíč API ${keyId}?",
|
||||
"fullAccess": "všechno",
|
||||
"getToken": "Získat token",
|
||||
"name": "Jméno",
|
||||
"nameDesc": "Jak chcete nazvat tento token API? ",
|
||||
@ -218,6 +219,7 @@
|
||||
"not-downloaded": "Zdá se, že nemůžeme najít váš spustitelný soubor. Bylo jeho stahování dokončeno? Jsou oprávnění nastavena na spustitelný soubor?",
|
||||
"portReminder": "Zjistili jsme, že server {} byl spuštěn poprvé. Ujistěte se, že jste přesměrovali port {} přes váš směrovač/firewall, aby byl tento port vzdáleně přístupný z internetu.",
|
||||
"privMsg": "a ",
|
||||
"return": "vrátit se na hlavní stránku",
|
||||
"serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte",
|
||||
"serverJars2": "pro aktualní informace.",
|
||||
"start-error": "Server {} se nepodařilo spustit s kódem chyby: {}",
|
||||
@ -612,7 +614,7 @@
|
||||
"credits": "Zásluhy",
|
||||
"dashboard": "Ovládací panel",
|
||||
"documentation": "Dokumentace",
|
||||
"inApp": "V app dokumentaci",
|
||||
"inApp": "V lokalní dokumentaci",
|
||||
"navigation": "Navigace",
|
||||
"newServer": "Vytvořit nový server",
|
||||
"servers": "Servery"
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Erstellt",
|
||||
"deleteKeyConfirmation": "Möchten Sie diesen API Schlüssel löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"deleteKeyConfirmationTitle": "Folgenden API Schlüssel löschen: ${keyId}?",
|
||||
"fullAccess": "Vollzugriff",
|
||||
"getToken": "Schlüssel erhalten",
|
||||
"name": "Name",
|
||||
"nameDesc": "Wie soll der API Schlüssel genannt werden? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "Crafty kann die auszuführende Datei nicht finden. Ist der Download abgeschlossen? Sind die Berechtigungen für Crafty korrekt?",
|
||||
"portReminder": "Wir haben festgestellt, dass dies das erste Mal ist, dass {} ausgeführt wurde. Stellen Sie sicher, dass Sie Port {} durch Ihren Router/Firewall weiterleiten, um den Fernzugriff aus dem Internet zu ermöglichen.",
|
||||
"privMsg": "und der/die/das ",
|
||||
"return": "Zurück zum Dashboard",
|
||||
"serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ",
|
||||
"serverJars2": "um die aktuellsten Informationen zu erhalten.",
|
||||
"start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Created",
|
||||
"deleteKeyConfirmation": "Do you want to delete this API key? This cannot be undone.",
|
||||
"deleteKeyConfirmationTitle": "Remove API key ${keyId}?",
|
||||
"fullAccess": "Full Access",
|
||||
"getToken": "Get A Token",
|
||||
"name": "Name",
|
||||
"nameDesc": "What would you like to call this API token? ",
|
||||
@ -28,7 +29,6 @@
|
||||
"permName": "Permission Name",
|
||||
"perms": "Permissions",
|
||||
"server": "Server: ",
|
||||
"superUser": "Super User",
|
||||
"yes": "Yes"
|
||||
},
|
||||
"base": {
|
||||
@ -203,6 +203,7 @@
|
||||
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?",
|
||||
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
||||
"privMsg": "and the ",
|
||||
"return": "Return to Dashboard",
|
||||
"serverJars1": "Server JARs API unreachable. Please check",
|
||||
"serverJars2": "for the most up to date information.",
|
||||
"start-error": "Server {} failed to start with error code: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Creado",
|
||||
"deleteKeyConfirmation": "¿Quieres eliminar esta clave de API? Esto no se puede deshacer.",
|
||||
"deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?",
|
||||
"fullAccess": "Acceso completo",
|
||||
"getToken": "Conseguir un Token",
|
||||
"name": "Nombre",
|
||||
"nameDesc": "¿Como te gustaría llamar a este Token de API? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "No podemos encontrar el archivo ejecutable. ¿Ha terminado de descargarse? ¿Están los permisos puestos como ejecutable?",
|
||||
"portReminder": "Detectamos que es la primera vez que se inicia {}. Asegúrese de configurar el puerto {} a través de su router/firewall para hacer el servidor accesible por Internet.",
|
||||
"privMsg": "y el ",
|
||||
"return": "Volver al panel de control",
|
||||
"serverJars1": "API de Servidor JAR no disponible. por favor, compruebe",
|
||||
"serverJars2": "para la información más actualizada.",
|
||||
"start-error": "Servidor {} fallo al iniciar con código de error: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Crée",
|
||||
"deleteKeyConfirmation": "Es-tu sûr de vouloir supprimer cette clé API? Tu ne pourras plus revenir en arrière.",
|
||||
"deleteKeyConfirmationTitle": "Supprimer la clé API ${keyId}?",
|
||||
"fullAccess": "Accès Complet",
|
||||
"getToken": "Obtenir un Jeton",
|
||||
"name": "Nom",
|
||||
"nameDesc": "Comment appeler ce Jeton d'API ? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "Nous ne parvenons pas à trouver le fichier exécutable. A-t-il fini de Télécharger ? Les permissions permettent elles l'exécution ?",
|
||||
"portReminder": "Nous avons détecté que c'est la première fois que {} est exécuté. Assurez-vous de transférer le port {} via votre routeur/pare-feu pour le rendre accessible à distance depuis Internet.",
|
||||
"privMsg": "et le ",
|
||||
"return": "Revenir au Tableau de Bord",
|
||||
"serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier",
|
||||
"serverJars2": "pour les informations les plus à jour.",
|
||||
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "נוצר",
|
||||
"deleteKeyConfirmation": "האם ברצונך למחוק מפתח API זה? אי אפשר לבטל את זה.",
|
||||
"deleteKeyConfirmationTitle": "? ${keyId} API-להסיר את מפתח ה",
|
||||
"fullAccess": "גישה מלאה להכל",
|
||||
"getToken": "קבלת אסימון",
|
||||
"name": "שם",
|
||||
"nameDesc": "הזה API-איך תרצו לקרוא לאסימון ה",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?",
|
||||
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
|
||||
"privMsg": "וה",
|
||||
"return": "חזרה לפאנל",
|
||||
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
|
||||
"serverJars2": "למידע מעודכן ביותר.",
|
||||
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Creato",
|
||||
"deleteKeyConfirmation": "Vuoi cancellare questa chiave API? Non puoi tornare indietro.",
|
||||
"deleteKeyConfirmationTitle": "Rimuovere la chiave API ${keyId}?",
|
||||
"fullAccess": " Accesso completo",
|
||||
"getToken": "Prendi un Token",
|
||||
"name": "Nome",
|
||||
"nameDesc": "Come desideri chiamare questo Token API? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?",
|
||||
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
||||
"privMsg": "e il ",
|
||||
"return": "Torna alla pagina iniziale",
|
||||
"serverJars1": "API JAR del server non raggiungibile. Si prega di controllare",
|
||||
"serverJars2": "per informazioni più aggiornate.",
|
||||
"start-error": "Server {} failed to start with error code: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "CREATED",
|
||||
"deleteKeyConfirmation": "U SURE U WANTZ TO DELETE DIS? CAN'T UNDO!",
|
||||
"deleteKeyConfirmationTitle": "I CAN EATZ IT??? : ${keyId}?",
|
||||
"fullAccess": "All da Doors Open",
|
||||
"getToken": "GIT TOKEN",
|
||||
"name": "NAME",
|
||||
"nameDesc": "WUT WUD U LIEK 2 CALL DIS API TOKEN? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "SOZ BUT I FAILDZ CAN'T SEEM TO FINDZ YOUR FISH. PLZ GIB MEZ IT. I HUNGRY.",
|
||||
"portReminder": "WE HAS DETECTD DIS AR TEH FURST TIEM {} IZ BEAN RUN. IF U WANTS IT ACESIBLE TO NEIGHBORHOOD CATS PLZ UNLOCK CAT_FLAP, {}, THRU UR ROUTR IF U HAS NOT DUN SO.",
|
||||
"privMsg": "AND THEEZ ",
|
||||
"return": "Go Bak to Dashbored",
|
||||
"serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ",
|
||||
"serverJars2": "TO SEE NEWZ STUFFZ.",
|
||||
"start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Izveidots",
|
||||
"deleteKeyConfirmation": "Vai vēlies dzēst šo API atslēgu? Šo nevar atdarīt.",
|
||||
"deleteKeyConfirmationTitle": "Noņemt API atslēgu ${keyId}?",
|
||||
"fullAccess": "Pilna piekļuve",
|
||||
"getToken": "Saņemt Pilnvaru (Token)",
|
||||
"name": "Nosaukums",
|
||||
"nameDesc": "Kā jūs vēlaties nosaukt šo Pilnvaru (Token)? ",
|
||||
@ -204,6 +205,7 @@
|
||||
"not-downloaded": "Mēs nevaram atrast jūsu izpildāmo failu. Vai tas ir beidzis lejupielādēties? Vai tā peikļuves ir uzstādītas kā palaižamas?",
|
||||
"portReminder": "Mēs noteicām ka šī ir pirmā reize, kad {} ir ticis palaists. Pārliecinies izlaist portu {} cauri savam rūterim/ugunsmūrim lai padarītu šo attāli pieejamu no interneta.",
|
||||
"privMsg": "un ",
|
||||
"return": "Atgriezties uz pārskatu",
|
||||
"serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet",
|
||||
"serverJars2": "priekš jaunākās informācijas.",
|
||||
"start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Gecreëerd",
|
||||
"deleteKeyConfirmation": "Wilt u deze API sleutel verwijderen? Dit kan niet ongedaan gemaakt worden.",
|
||||
"deleteKeyConfirmationTitle": "API sleutel verwijderen ${keyId}?",
|
||||
"fullAccess": "Volledige toegang",
|
||||
"getToken": "Verkrijg een Token",
|
||||
"name": "Naam",
|
||||
"nameDesc": "Hoe wilt u dit API token noemen? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "We kunnen uw uitvoerbare bestand niet vinden. Is het klaar met downloaden? Zijn de rechten ingesteld op uitvoerbaar?",
|
||||
"portReminder": "We hebben ontdekt dat dit de eerste keer is dat {} wordt uitgevoerd. Zorg ervoor dat u poort {} doorstuurt via uw router/firewall om deze op afstand toegankelijk te maken vanaf het internet.",
|
||||
"privMsg": "en de ",
|
||||
"return": "Terug naar Dashboard",
|
||||
"serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft",
|
||||
"serverJars2": "voor de meest recente informatie.",
|
||||
"start-error": "Server {} kan niet starten met foutcode: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Stworzono",
|
||||
"deleteKeyConfirmation": "Czy chcesz usunąć ten klucz API? Nie można tego cofnąć.",
|
||||
"deleteKeyConfirmationTitle": "Usunąć Klucz API ${keyId}?",
|
||||
"fullAccess": "Pełny dostęp",
|
||||
"getToken": "Zdobądź token",
|
||||
"name": "Nazwa",
|
||||
"nameDesc": "Jak chcesz nazwać ten klucz API? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "Nie możemy znaleść twojego pliku serwera. Czy skończył się pobierać? Czy permisje są ustawione na wykonywanle?",
|
||||
"portReminder": "Zauważyliśmy że to jest pierwszy raz {} kiedy był włączony. Upewnij się że otworzyłeś port {} na swoim routerze/firewallu aby korzystać z tego poza domem.",
|
||||
"privMsg": "i także ",
|
||||
"return": "Powrót do panelu",
|
||||
"serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź",
|
||||
"serverJars2": "dla najnowzsych informacji.",
|
||||
"start-error": "Serwer {} nie mógł się odpalić z powodu: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "สร้างเมื่อ",
|
||||
"deleteKeyConfirmation": "คุณต้องการลบคีย์ API นี้หรือไม่ สิ่งนี้ไม่สามารถยกเลิกได้",
|
||||
"deleteKeyConfirmationTitle": "ลบคีย์ API นี้ ${keyId} หรือไม่?",
|
||||
"fullAccess": "เข้าถึงได้ทั้งหมด",
|
||||
"getToken": "แสดงโทเค็น",
|
||||
"name": "ชื่อ",
|
||||
"nameDesc": "คุณต้องการเรียกโทเค็น API นี้ว่าอะไร ? ",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "ดูเหมือนว่าเราจะไม่พบแฟ้มกระทำการของคุณ (.jar) ตรวจสอบให้แน่ใจว่าการดาวโหลดน์เสร็จสิ้นแล้ว, การอนุญาตถูกตั้งไปยังแฟ้มกระทำการหรือไม่?",
|
||||
"portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล",
|
||||
"privMsg": "และ ",
|
||||
"return": "ย้อนกลับไปยังแผงควบคุม",
|
||||
"serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ",
|
||||
"serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด",
|
||||
"start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Oluşturuldu",
|
||||
"deleteKeyConfirmation": "Bu API anahtarını silmek istediğine emin misin? Bu geri alınamaz.",
|
||||
"deleteKeyConfirmationTitle": "${keyId} API anahtarını kaldırma işlemi.",
|
||||
"fullAccess": "Tam Erişim",
|
||||
"getToken": "Bir Token Al",
|
||||
"name": "Ad",
|
||||
"nameDesc": "Bu API tokeninin adı ne olsun?",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "Çalıştırılabilir dosyanızı bulamıyoruz. İndirme işlemi tamamlandı mı? İzinler çalıştırılabilir olarak ayarlandı mı?",
|
||||
"portReminder": "{} ilk kez çalıştırılıyor olduğunu tespit ettik. Bunu internetten uzaktan erişilebilir kılmak için {} bağlantı noktasını yönlendiriciniz/güvenlik duvarınız üzerinden ilettiğinizden emin olun.",
|
||||
"privMsg": "ve ",
|
||||
"return": "Arayüze Geri Dön",
|
||||
"serverJars1": "Sunucu JARs API'ına erişilemiyor.",
|
||||
"serverJars2": "en güncel bilgilere sahiptir",
|
||||
"start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "Створений",
|
||||
"deleteKeyConfirmation": "Ви дійсно бажаєте видалити API ключ? Це незворотня дія.",
|
||||
"deleteKeyConfirmationTitle": "Видалення API ключ ${keyId}?",
|
||||
"fullAccess": "Повний доступ",
|
||||
"getToken": "Отримати Токен",
|
||||
"name": "Ім'я",
|
||||
"nameDesc": "Як ви хочете назвати даний API токен?",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?",
|
||||
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
|
||||
"privMsg": "і ",
|
||||
"return": "Повернутись до панелі",
|
||||
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
||||
"serverJars2": "для найактуальнішої інформації.",
|
||||
"start-error": "Сервер {} не запустився через помилку: {}",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"created": "创建时间",
|
||||
"deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。",
|
||||
"deleteKeyConfirmationTitle": "删除 API 密钥 ${keyId}?",
|
||||
"fullAccess": "完全访问",
|
||||
"getToken": "获得一个令牌",
|
||||
"name": "名称",
|
||||
"nameDesc": "你想把这个 API 令牌叫做什么?",
|
||||
@ -203,6 +204,7 @@
|
||||
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
|
||||
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
||||
"privMsg": "以及",
|
||||
"return": "返回仪表板",
|
||||
"serverJars1": "无法访问服务器 JAR API。请检查",
|
||||
"serverJars2": "以获取最新信息。",
|
||||
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
||||
|
Loading…
Reference in New Issue
Block a user