Merge branch 'dev' into tweak/json-audit-log

This commit is contained in:
Zedifus 2024-05-09 21:03:26 +01:00
commit 39a98f2b5e
42 changed files with 322 additions and 193 deletions

View File

@ -5,7 +5,7 @@ yamllint:
stage: lint stage: lint
image: registry.gitlab.com/pipeline-components/yamllint:latest image: registry.gitlab.com/pipeline-components/yamllint:latest
tags: tags:
- docker - saas-linux-medium-amd64
rules: rules:
- if: "$CODE_QUALITY_DISABLED" - if: "$CODE_QUALITY_DISABLED"
when: never when: never
@ -18,7 +18,7 @@ jsonlint:
stage: lint stage: lint
image: registry.gitlab.com/pipeline-components/jsonlint:latest image: registry.gitlab.com/pipeline-components/jsonlint:latest
tags: tags:
- docker - saas-linux-medium-amd64
rules: rules:
- if: "$CODE_QUALITY_DISABLED" - if: "$CODE_QUALITY_DISABLED"
when: never when: never
@ -33,7 +33,7 @@ black:
stage: lint stage: lint
image: registry.gitlab.com/pipeline-components/black:latest image: registry.gitlab.com/pipeline-components/black:latest
tags: tags:
- docker - saas-linux-medium-amd64
rules: rules:
- if: "$CODE_QUALITY_DISABLED" - if: "$CODE_QUALITY_DISABLED"
when: never when: never
@ -46,7 +46,7 @@ pylint:
stage: lint stage: lint
image: registry.gitlab.com/pipeline-components/pylint:latest image: registry.gitlab.com/pipeline-components/pylint:latest
tags: tags:
- docker - saas-linux-medium-amd64
rules: rules:
- if: "$CODE_QUALITY_DISABLED" - if: "$CODE_QUALITY_DISABLED"
when: never when: never
@ -69,7 +69,7 @@ sonarcloud-check:
name: sonarsource/sonar-scanner-cli:latest name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""] entrypoint: [""]
tags: tags:
- docker - saas-linux-medium-amd64
rules: rules:
- if: "$SONAR_TOKEN == null" - if: "$SONAR_TOKEN == null"
when: never when: never
@ -91,7 +91,7 @@ lang-check:
stage: lint stage: lint
image: alpine:latest image: alpine:latest
tags: tags:
- docker - saas-linux-medium-amd64
rules: rules:
- if: "$CODE_QUALITY_DISABLED" - if: "$CODE_QUALITY_DISABLED"
when: never when: never

View File

@ -1,13 +1,15 @@
# Changelog # Changelog
## --- [4.3.3] - 2024/TBD ## --- [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 ### New features
TBD TBD
### Bug fixes ### Bug fixes
TBD - Reset query arguments on login if `?next` is not available ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/750))
### Tweaks ### 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 ### Lang
TBD - Changes of phrase in `cs_CS` translation ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/749))
<br><br> <br><br>
## --- [4.3.2] - 2024/04/07 ## --- [4.3.2] - 2024/04/07

View File

@ -17,6 +17,10 @@ class ServerPermsController:
def get_server_user_list(server_id): def get_server_user_list(server_id):
return PermissionsServers.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 @staticmethod
def list_defined_permissions(): def list_defined_permissions():
permissions_list = PermissionsServers.get_permissions_list() permissions_list = PermissionsServers.get_permissions_list()
@ -61,6 +65,22 @@ class ServerPermsController:
def get_permissions_mask(role_id, server_id): def get_permissions_mask(role_id, server_id):
return PermissionsServers.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 @staticmethod
def set_permission( def set_permission(
permission_mask, permission_tested: EnumPermissionsServer, value permission_mask, permission_tested: EnumPermissionsServer, value
@ -82,6 +102,11 @@ class ServerPermsController:
def get_api_key_permissions_list(key: ApiKeys, server_id: str): def get_api_key_permissions_list(key: ApiKeys, server_id: str):
return PermissionsServers.get_api_key_permissions_list(key, server_id) 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 @staticmethod
def get_authorized_servers_stats_from_roles(user_id): def get_authorized_servers_stats_from_roles(user_id):
user_roles = HelperUsers.get_user_roles_id(user_id) user_roles = HelperUsers.get_user_roles_id(user_id)

View File

@ -187,7 +187,7 @@ class PermissionsCrafty:
@staticmethod @staticmethod
def get_api_key_permissions_list(key: ApiKeys): def get_api_key_permissions_list(key: ApiKeys):
user = HelperUsers.get_user(key.user_id) 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() return PermissionsCrafty.get_permissions_list()
if user["superuser"]: if user["superuser"]:
# User is superuser but API key isn't # User is superuser but API key isn't

View File

@ -264,7 +264,7 @@ class PermissionsServers:
@staticmethod @staticmethod
def get_api_key_permissions_list(key: ApiKeys, server_id: str): def get_api_key_permissions_list(key: ApiKeys, server_id: str):
user = HelperUsers.get_user(key.user_id) 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() return PermissionsServers.get_permissions_list()
roles_list = HelperUsers.get_user_roles_id(user["user_id"]) roles_list = HelperUsers.get_user_roles_id(user["user_id"])
role_server = ( role_server = (

View File

@ -71,7 +71,7 @@ class ApiKeys(BaseModel):
user_id = ForeignKeyField(Users, backref="api_token", index=True) user_id = ForeignKeyField(Users, backref="api_token", index=True)
server_permissions = CharField(default="00000000") server_permissions = CharField(default="00000000")
crafty_permissions = CharField(default="000") crafty_permissions = CharField(default="000")
superuser = BooleanField(default=False) full_access = BooleanField(default=False)
class Meta: class Meta:
table_name = "api_keys" table_name = "api_keys"
@ -408,7 +408,7 @@ class HelperUsers:
def add_user_api_key( def add_user_api_key(
name: str, name: str,
user_id: str, user_id: str,
superuser: bool = False, full_access: bool = False,
server_permissions_mask: t.Optional[str] = None, server_permissions_mask: t.Optional[str] = None,
crafty_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 if crafty_permissions_mask is not None
else {} else {}
), ),
ApiKeys.superuser: superuser, ApiKeys.full_access: full_access,
} }
).execute() ).execute()

View File

@ -182,6 +182,7 @@ class BaseHandler(tornado.web.RequestHandler):
t.List[str], t.List[str],
bool, bool,
t.Dict[str, t.Any], t.Dict[str, t.Any],
str,
] ]
]: ]:
try: try:
@ -190,9 +191,10 @@ class BaseHandler(tornado.web.RequestHandler):
) )
superuser = user["superuser"] superuser = user["superuser"]
server_permissions_api_mask = ""
if api_key is not None: 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() exec_user_role = set()
if superuser: if superuser:
authorized_servers = self.controller.servers.get_all_defined_servers() authorized_servers = self.controller.servers.get_all_defined_servers()
@ -214,6 +216,7 @@ class BaseHandler(tornado.web.RequestHandler):
user["user_id"] user["user_id"]
) )
) )
logger.debug(user["roles"]) logger.debug(user["roles"])
for r in user["roles"]: for r in user["roles"]:
role = self.controller.roles.get_role(r) role = self.controller.roles.get_role(r)
@ -234,6 +237,7 @@ class BaseHandler(tornado.web.RequestHandler):
exec_user_role, exec_user_role,
superuser, superuser,
user, user,
server_permissions_api_mask,
) )
logging.debug("Auth unsuccessful") logging.debug("Auth unsuccessful")
auth_log.error( auth_log.error(

View File

@ -168,7 +168,7 @@ class PanelHandler(BaseHandler):
# Commented out because there is no server access control for API keys, # Commented out because there is no server access control for API keys,
# they just inherit from the host user # they just inherit from the host user
# if api_key is not None: # if api_key is not None:
# superuser = superuser and api_key.superuser # superuser = superuser and api_key.full_access
if server_id is None: if server_id is None:
self.redirect("/panel/error?error=Invalid Server ID") self.redirect("/panel/error?error=Invalid Server ID")
@ -242,7 +242,7 @@ class PanelHandler(BaseHandler):
api_key, _token_data, exec_user = self.current_user api_key, _token_data, exec_user = self.current_user
superuser = exec_user["superuser"] superuser = exec_user["superuser"]
if api_key is not None: 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 if superuser: # TODO: Figure out a better solution
defined_servers = self.controller.servers.list_defined_servers() defined_servers = self.controller.servers.list_defined_servers()
@ -351,7 +351,7 @@ class PanelHandler(BaseHandler):
"created": api_key.created, "created": api_key.created,
"server_permissions": api_key.server_permissions, "server_permissions": api_key.server_permissions,
"crafty_permissions": api_key.crafty_permissions, "crafty_permissions": api_key.crafty_permissions,
"superuser": api_key.superuser, "full_access": api_key.full_access,
} }
if api_key is not None if api_key is not None
else None else None
@ -1356,6 +1356,9 @@ class PanelHandler(BaseHandler):
page_data["crafty_permissions_all"] = ( page_data["crafty_permissions_all"] = (
self.controller.crafty_perms.list_defined_crafty_permissions() 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: if user_id is None:
self.redirect("/panel/error?error=Invalid User ID") self.redirect("/panel/error?error=Invalid User ID")

View File

@ -48,7 +48,10 @@ class PublicHandler(BaseHandler):
} }
if self.request.query: if self.request.query:
page_data["query"] = self.request.query_arguments.get("next")[0].decode() request_query = self.request.query_arguments.get("next")
if not request_query:
self.redirect("/login")
page_data["query"] = request_query[0].decode()
# sensible defaults # sensible defaults
template = "public/404.html" template = "public/404.html"

View File

@ -18,13 +18,14 @@ class ApiServersServerActionHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.COMMANDS
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Commands permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -26,12 +26,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.BACKUP self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.finish_json(200, self.controller.management.get_backup_config(server_id)) 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) backup_conf = self.controller.management.get_backup_config(server_id)
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.BACKUP self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
@ -89,12 +93,14 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.BACKUP self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -42,12 +42,14 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.BACKUP self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.finish_json(200, self.controller.management.get_backup_config(server_id)) 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.BACKUP
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -80,16 +80,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) 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 ( if (
EnumPermissionsServer.FILES EnumPermissionsServer.FILES not in server_permissions
not in self.controller.server_perms.get_user_id_permissions_list( and EnumPermissionsServer.BACKUP not in server_permissions
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
)
): ):
# if the user doesn't have Files or Backup permission, return an error # if the user doesn't have Files or Backup permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.FILES
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Files permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try: try:
@ -254,13 +255,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.FILES
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Files permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try: try:
@ -307,13 +309,14 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.FILES
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Files permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try: try:
@ -373,13 +376,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.FILES
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Files permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try: try:
@ -438,13 +442,14 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.FILES
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Files permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try: try:
@ -504,13 +509,14 @@ class ApiServersServerFilesZipHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.FILES
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Files permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try: try:

View File

@ -102,13 +102,14 @@ class ApiServersServerIndexHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.CONFIG
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Config permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.CONFIG
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Config permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -30,13 +30,14 @@ class ApiServersServerLogsHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.LOGS
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Logs permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -16,13 +16,14 @@ class ApiServersServerStdinHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.COMMANDS
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Commands permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -78,13 +78,14 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler):
if server_id not in [str(x["server_id"]) for x in auth_data[0]]: 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.SCHEDULE
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
data["server_id"] = server_id data["server_id"] = server_id

View File

@ -54,12 +54,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.SCHEDULE self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.finish_json(200, self.controller.management.get_scheduled_task(task_id)) self.finish_json(200, self.controller.management.get_scheduled_task(task_id))
@ -68,12 +70,14 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.SCHEDULE self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.SCHEDULE
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})

View File

@ -38,12 +38,14 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.CONFIG self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.finish_json( 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.CONFIG
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
data["server_id"] = server_id data["server_id"] = server_id

View File

@ -39,12 +39,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.CONFIG self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
if ( if (
@ -66,12 +68,14 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
auth_data = self.authenticate_user() auth_data = self.authenticate_user()
if not auth_data: if not auth_data:
return return
if ( mask = self.controller.server_perms.get_lowest_api_perm_mask(
EnumPermissionsServer.CONFIG self.controller.server_perms.get_user_permissions_mask(
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.CONFIG
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) 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 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 # if the user doesn't have access to the server, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
mask = self.controller.server_perms.get_lowest_api_perm_mask(
if ( self.controller.server_perms.get_user_permissions_mask(
EnumPermissionsServer.CONFIG
not in self.controller.server_perms.get_user_id_permissions_list(
auth_data[4]["user_id"], server_id 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 # if the user doesn't have Schedule permission, return an error
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
webhook = self.controller.management.get_webhook_by_id(webhook_id) webhook = self.controller.management.get_webhook_by_id(webhook_id)

View File

@ -75,7 +75,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
"name": key.name, "name": key.name,
"server_permissions": key.server_permissions, "server_permissions": key.server_permissions,
"crafty_permissions": key.crafty_permissions, "crafty_permissions": key.crafty_permissions,
"superuser": key.superuser, "full_access": key.full_access,
} }
) )
self.finish_json( self.finish_json(
@ -99,7 +99,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
"type": "string", "type": "string",
"pattern": "^[01]{3}$", # 8 bits, see EnumPermissionsCrafty "pattern": "^[01]{3}$", # 8 bits, see EnumPermissionsCrafty
}, },
"superuser": {"type": "boolean"}, "full_access": {"type": "boolean"},
}, },
"additionalProperties": False, "additionalProperties": False,
"minProperties": 1, "minProperties": 1,
@ -163,7 +163,7 @@ class ApiUsersUserKeyHandler(BaseApiHandler):
key_id = self.controller.users.add_user_api_key( key_id = self.controller.users.add_user_api_key(
data["name"], data["name"],
user_id, user_id,
data["superuser"], data["full_access"],
data["server_permissions_mask"], data["server_permissions_mask"],
data["crafty_permissions_mask"], data["crafty_permissions_mask"],
) )

View File

@ -30,7 +30,7 @@ class ServerHandler(BaseHandler):
) = self.current_user ) = self.current_user
superuser = exec_user["superuser"] superuser = exec_user["superuser"]
if api_key is not None: if api_key is not None:
superuser = superuser and api_key.superuser superuser = superuser and api_key.full_access
if superuser: if superuser:
defined_servers = self.controller.servers.list_defined_servers() defined_servers = self.controller.servers.list_defined_servers()
@ -124,7 +124,7 @@ class ServerHandler(BaseHandler):
"created": api_key.created, "created": api_key.created,
"server_permissions": api_key.server_permissions, "server_permissions": api_key.server_permissions,
"crafty_permissions": api_key.crafty_permissions, "crafty_permissions": api_key.crafty_permissions,
"superuser": api_key.superuser, "full_access": api_key.full_access,
} }
if api_key is not None if api_key is not None
else None else None

View File

@ -42,7 +42,7 @@ class UploadHandler(BaseHandler):
if self.upload_type == "server_import": if self.upload_type == "server_import":
superuser = exec_user["superuser"] superuser = exec_user["superuser"]
if api_key is not None: 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"] user_id = exec_user["user_id"]
stream_size_value = self.helper.get_setting("stream_size_GB") stream_size_value = self.helper.get_setting("stream_size_GB")
@ -133,7 +133,7 @@ class UploadHandler(BaseHandler):
elif self.upload_type == "background": elif self.upload_type == "background":
superuser = exec_user["superuser"] superuser = exec_user["superuser"]
if api_key is not None: 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"] user_id = exec_user["user_id"]
stream_size_value = self.helper.get_setting("stream_size_GB") 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) server_id = self.get_argument("server_id", None)
superuser = exec_user["superuser"] superuser = exec_user["superuser"]
if api_key is not None: 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"] user_id = exec_user["user_id"]
stream_size_value = self.helper.get_setting("stream_size_GB") stream_size_value = self.helper.get_setting("stream_size_GB")

View File

@ -58,7 +58,7 @@
<!--<th>ID</th>--> <!--<th>ID</th>-->
<th>{{ translate('apiKeys', 'name', data['lang']) }}</th> <th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'created', 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', 'perms', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th> <th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
</tr> </tr>
@ -70,7 +70,7 @@
<td>{{ apikey.name }}</td> <td>{{ apikey.name }}</td>
<td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td> <td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
<td> <td>
{% if apikey.superuser %} {% if apikey.full_access %}
<span class="text-success"> <span class="text-success">
<i class="fas fa-check-square"></i> {{ <i class="fas fa-check-square"></i> {{
translate('apiKeys', 'yes', data['lang']) }} translate('apiKeys', 'yes', data['lang']) }}
@ -148,9 +148,15 @@
}}</label> }}</label>
</td> </td>
<td> <td>
{% if permission in data['user_crafty_permissions'] %}
<input type="checkbox" class="crafty_perm" <input type="checkbox" class="crafty_perm"
id="permission_{{ permission.name }}" id="permission_{{ permission.name }}"
name="permission_{{ permission.name }}" value="1"> 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> </td>
</tr> </tr>
{% end %} {% end %}
@ -158,8 +164,8 @@
</tbody> </tbody>
</table> </table>
<label for="superuser">Superuser</label> <label for="full_access">{{translate('apiKeys', 'fullAccess', data['lang'])}}</label>
<input type="checkbox" class="" id="superuser" name="superuser" value="1"> <input type="checkbox" class="" id="full_access" name="full_access" value="1">
<br /> <br />
@ -240,7 +246,7 @@
"name": formDataObject.name, "name": formDataObject.name,
"server_permissions_mask": server_permissions, "server_permissions_mask": server_permissions,
"crafty_permissions_mask": crafty_permissions, "crafty_permissions_mask": crafty_permissions,
"superuser": $("#superuser").prop('checked'), "full_access": $("#full_access").prop('checked'),
}); });
console.log(formDataJsonString); console.log(formDataJsonString);

View File

@ -1,5 +1,6 @@
<!DOCTYPE html> <!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> <head>
<!-- Required meta tags --> <!-- Required meta tags -->
@ -60,6 +61,11 @@
<b>{{ translate('error', 'hereIsTheError', data['lang']) }}: {{data['error']}}</b><br /><br /> <b>{{ translate('error', 'hereIsTheError', data['lang']) }}: {{data['error']}}</b><br /><br />
That's all the help I can give you - Godspeed That's all the help I can give you - Godspeed
<br /><br /> <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', <a class="d-inline font-weight-medium" href="https://discord.gg/9VJPhCE"> {{ translate('error',
'contact', data['lang']) }}</a> 'contact', data['lang']) }}</a>
</p> </p>

View File

@ -171,7 +171,6 @@
//Create an object from the form data entries //Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries()); let formDataObject = Object.fromEntries(formData.entries());
console.log(formDataObject)
let res = await fetch(`/login`, { let res = await fetch(`/login`, {
method: 'POST', method: 'POST',
headers: { headers: {

View 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.
"""

View File

@ -20,6 +20,7 @@
"created": "Vytvořen", "created": "Vytvořen",
"deleteKeyConfirmation": "Chcete tento API klíč odstranit? Tuto akci nelze vrátit zpět.", "deleteKeyConfirmation": "Chcete tento API klíč odstranit? Tuto akci nelze vrátit zpět.",
"deleteKeyConfirmationTitle": "Odstranit klíč API ${keyId}?", "deleteKeyConfirmationTitle": "Odstranit klíč API ${keyId}?",
"fullAccess": "všechno",
"getToken": "Získat token", "getToken": "Získat token",
"name": "Jméno", "name": "Jméno",
"nameDesc": "Jak chcete nazvat tento token API? ", "nameDesc": "Jak chcete nazvat tento token API? ",
@ -219,6 +220,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?", "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.", "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 ", "privMsg": "a ",
"return": "vrátit se na hlavní stránku",
"serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte", "serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte",
"serverJars2": "pro aktualní informace.", "serverJars2": "pro aktualní informace.",
"start-error": "Server {} se nepodařilo spustit s kódem chyby: {}", "start-error": "Server {} se nepodařilo spustit s kódem chyby: {}",
@ -613,7 +615,7 @@
"credits": "Zásluhy", "credits": "Zásluhy",
"dashboard": "Ovládací panel", "dashboard": "Ovládací panel",
"documentation": "Dokumentace", "documentation": "Dokumentace",
"inApp": "V app dokumentaci", "inApp": "V lokalní dokumentaci",
"navigation": "Navigace", "navigation": "Navigace",
"newServer": "Vytvořit nový server", "newServer": "Vytvořit nový server",
"servers": "Servery" "servers": "Servery"

View File

@ -20,6 +20,7 @@
"created": "Erstellt", "created": "Erstellt",
"deleteKeyConfirmation": "Möchten Sie diesen API Schlüssel löschen? Diese Aktion kann nicht rückgängig gemacht werden.", "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}?", "deleteKeyConfirmationTitle": "Folgenden API Schlüssel löschen: ${keyId}?",
"fullAccess": "Vollzugriff",
"getToken": "Schlüssel erhalten", "getToken": "Schlüssel erhalten",
"name": "Name", "name": "Name",
"nameDesc": "Wie soll der API Schlüssel genannt werden? ", "nameDesc": "Wie soll der API Schlüssel genannt werden? ",
@ -204,6 +205,7 @@
"not-downloaded": "Crafty kann die auszuführende Datei nicht finden. Ist der Download abgeschlossen? Sind die Berechtigungen für Crafty korrekt?", "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.", "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 ", "privMsg": "und der/die/das ",
"return": "Zurück zum Dashboard",
"serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ", "serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ",
"serverJars2": "um die aktuellsten Informationen zu erhalten.", "serverJars2": "um die aktuellsten Informationen zu erhalten.",
"start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden", "start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden",

View File

@ -20,6 +20,7 @@
"created": "Created", "created": "Created",
"deleteKeyConfirmation": "Do you want to delete this API key? This cannot be undone.", "deleteKeyConfirmation": "Do you want to delete this API key? This cannot be undone.",
"deleteKeyConfirmationTitle": "Remove API key ${keyId}?", "deleteKeyConfirmationTitle": "Remove API key ${keyId}?",
"fullAccess": "Full Access",
"getToken": "Get A Token", "getToken": "Get A Token",
"name": "Name", "name": "Name",
"nameDesc": "What would you like to call this API token? ", "nameDesc": "What would you like to call this API token? ",
@ -28,7 +29,6 @@
"permName": "Permission Name", "permName": "Permission Name",
"perms": "Permissions", "perms": "Permissions",
"server": "Server: ", "server": "Server: ",
"superUser": "Super User",
"yes": "Yes" "yes": "Yes"
}, },
"base": { "base": {
@ -204,6 +204,7 @@
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?", "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.", "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 ", "privMsg": "and the ",
"return": "Return to Dashboard",
"serverJars1": "Server JARs API unreachable. Please check", "serverJars1": "Server JARs API unreachable. Please check",
"serverJars2": "for the most up to date information.", "serverJars2": "for the most up to date information.",
"start-error": "Server {} failed to start with error code: {}", "start-error": "Server {} failed to start with error code: {}",

View File

@ -20,6 +20,7 @@
"created": "Creado", "created": "Creado",
"deleteKeyConfirmation": "¿Quieres eliminar esta clave de API? Esto no se puede deshacer.", "deleteKeyConfirmation": "¿Quieres eliminar esta clave de API? Esto no se puede deshacer.",
"deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?", "deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?",
"fullAccess": "Acceso completo",
"getToken": "Conseguir un Token", "getToken": "Conseguir un Token",
"name": "Nombre", "name": "Nombre",
"nameDesc": "¿Como te gustaría llamar a este Token de API? ", "nameDesc": "¿Como te gustaría llamar a este Token de API? ",
@ -204,6 +205,7 @@
"not-downloaded": "No podemos encontrar el archivo ejecutable. ¿Ha terminado de descargarse? ¿Están los permisos puestos como ejecutable?", "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.", "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 ", "privMsg": "y el ",
"return": "Volver al panel de control",
"serverJars1": "API de Servidor JAR no disponible. por favor, compruebe", "serverJars1": "API de Servidor JAR no disponible. por favor, compruebe",
"serverJars2": "para la información más actualizada.", "serverJars2": "para la información más actualizada.",
"start-error": "Servidor {} fallo al iniciar con código de error: {}", "start-error": "Servidor {} fallo al iniciar con código de error: {}",

View File

@ -20,6 +20,7 @@
"created": "Crée", "created": "Crée",
"deleteKeyConfirmation": "Es-tu sûr de vouloir supprimer cette clé API? Tu ne pourras plus revenir en arrière.", "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}?", "deleteKeyConfirmationTitle": "Supprimer la clé API ${keyId}?",
"fullAccess": "Accès Complet",
"getToken": "Obtenir un Jeton", "getToken": "Obtenir un Jeton",
"name": "Nom", "name": "Nom",
"nameDesc": "Comment appeler ce Jeton d'API ? ", "nameDesc": "Comment appeler ce Jeton d'API ? ",
@ -204,6 +205,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 ?", "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.", "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 ", "privMsg": "et le ",
"return": "Revenir au Tableau de Bord",
"serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier", "serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier",
"serverJars2": "pour les informations les plus à jour.", "serverJars2": "pour les informations les plus à jour.",
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}", "start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",

View File

@ -20,6 +20,7 @@
"created": "נוצר", "created": "נוצר",
"deleteKeyConfirmation": "האם ברצונך למחוק מפתח API זה? אי אפשר לבטל את זה.", "deleteKeyConfirmation": "האם ברצונך למחוק מפתח API זה? אי אפשר לבטל את זה.",
"deleteKeyConfirmationTitle": "? ${keyId} API-להסיר את מפתח ה", "deleteKeyConfirmationTitle": "? ${keyId} API-להסיר את מפתח ה",
"fullAccess": "גישה מלאה להכל",
"getToken": "קבלת אסימון", "getToken": "קבלת אסימון",
"name": "שם", "name": "שם",
"nameDesc": "הזה API-איך תרצו לקרוא לאסימון ה", "nameDesc": "הזה API-איך תרצו לקרוא לאסימון ה",
@ -204,6 +205,7 @@
"not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?", "not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?",
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.", "portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
"privMsg": "וה", "privMsg": "וה",
"return": "חזרה לפאנל",
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק", "serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
"serverJars2": "למידע מעודכן ביותר.", "serverJars2": "למידע מעודכן ביותר.",
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}", "start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",

View File

@ -20,6 +20,7 @@
"created": "Creato", "created": "Creato",
"deleteKeyConfirmation": "Vuoi cancellare questa chiave API? Non puoi tornare indietro.", "deleteKeyConfirmation": "Vuoi cancellare questa chiave API? Non puoi tornare indietro.",
"deleteKeyConfirmationTitle": "Rimuovere la chiave API ${keyId}?", "deleteKeyConfirmationTitle": "Rimuovere la chiave API ${keyId}?",
"fullAccess": " Accesso completo",
"getToken": "Prendi un Token", "getToken": "Prendi un Token",
"name": "Nome", "name": "Nome",
"nameDesc": "Come desideri chiamare questo Token API? ", "nameDesc": "Come desideri chiamare questo Token API? ",
@ -204,6 +205,7 @@
"not-downloaded": "We can't seem to find your executable file. Has it finished downloading? Are the permissions set to executable?", "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.", "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 ", "privMsg": "e il ",
"return": "Torna alla pagina iniziale",
"serverJars1": "API JAR del server non raggiungibile. Si prega di controllare", "serverJars1": "API JAR del server non raggiungibile. Si prega di controllare",
"serverJars2": "per informazioni più aggiornate.", "serverJars2": "per informazioni più aggiornate.",
"start-error": "Server {} failed to start with error code: {}", "start-error": "Server {} failed to start with error code: {}",

View File

@ -20,6 +20,7 @@
"created": "CREATED", "created": "CREATED",
"deleteKeyConfirmation": "U SURE U WANTZ TO DELETE DIS? CAN'T UNDO!", "deleteKeyConfirmation": "U SURE U WANTZ TO DELETE DIS? CAN'T UNDO!",
"deleteKeyConfirmationTitle": "I CAN EATZ IT??? : ${keyId}?", "deleteKeyConfirmationTitle": "I CAN EATZ IT??? : ${keyId}?",
"fullAccess": "All da Doors Open",
"getToken": "GIT TOKEN", "getToken": "GIT TOKEN",
"name": "NAME", "name": "NAME",
"nameDesc": "WUT WUD U LIEK 2 CALL DIS API TOKEN? ", "nameDesc": "WUT WUD U LIEK 2 CALL DIS API TOKEN? ",
@ -204,6 +205,7 @@
"not-downloaded": "SOZ BUT I FAILDZ CAN'T SEEM TO FINDZ YOUR FISH. PLZ GIB MEZ IT. I HUNGRY.", "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.", "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 ", "privMsg": "AND THEEZ ",
"return": "Go Bak to Dashbored",
"serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ", "serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ",
"serverJars2": "TO SEE NEWZ STUFFZ.", "serverJars2": "TO SEE NEWZ STUFFZ.",
"start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}", "start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}",

View File

@ -20,6 +20,7 @@
"created": "Izveidots", "created": "Izveidots",
"deleteKeyConfirmation": "Vai vēlies dzēst šo API atslēgu? Šo nevar atdarīt.", "deleteKeyConfirmation": "Vai vēlies dzēst šo API atslēgu? Šo nevar atdarīt.",
"deleteKeyConfirmationTitle": "Noņemt API atslēgu ${keyId}?", "deleteKeyConfirmationTitle": "Noņemt API atslēgu ${keyId}?",
"fullAccess": "Pilna piekļuve",
"getToken": "Saņemt Pilnvaru (Token)", "getToken": "Saņemt Pilnvaru (Token)",
"name": "Nosaukums", "name": "Nosaukums",
"nameDesc": "Kā jūs vēlaties nosaukt šo Pilnvaru (Token)? ", "nameDesc": "Kā jūs vēlaties nosaukt šo Pilnvaru (Token)? ",
@ -205,6 +206,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?", "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.", "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 ", "privMsg": "un ",
"return": "Atgriezties uz pārskatu",
"serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet", "serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet",
"serverJars2": "priekš jaunākās informācijas.", "serverJars2": "priekš jaunākās informācijas.",
"start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}", "start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}",

View File

@ -20,6 +20,7 @@
"created": "Gecreëerd", "created": "Gecreëerd",
"deleteKeyConfirmation": "Wilt u deze API sleutel verwijderen? Dit kan niet ongedaan gemaakt worden.", "deleteKeyConfirmation": "Wilt u deze API sleutel verwijderen? Dit kan niet ongedaan gemaakt worden.",
"deleteKeyConfirmationTitle": "API sleutel verwijderen ${keyId}?", "deleteKeyConfirmationTitle": "API sleutel verwijderen ${keyId}?",
"fullAccess": "Volledige toegang",
"getToken": "Verkrijg een Token", "getToken": "Verkrijg een Token",
"name": "Naam", "name": "Naam",
"nameDesc": "Hoe wilt u dit API token noemen? ", "nameDesc": "Hoe wilt u dit API token noemen? ",
@ -204,6 +205,7 @@
"not-downloaded": "We kunnen uw uitvoerbare bestand niet vinden. Is het klaar met downloaden? Zijn de rechten ingesteld op uitvoerbaar?", "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.", "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 ", "privMsg": "en de ",
"return": "Terug naar Dashboard",
"serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft", "serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft",
"serverJars2": "voor de meest recente informatie.", "serverJars2": "voor de meest recente informatie.",
"start-error": "Server {} kan niet starten met foutcode: {}", "start-error": "Server {} kan niet starten met foutcode: {}",

View File

@ -20,6 +20,7 @@
"created": "Stworzono", "created": "Stworzono",
"deleteKeyConfirmation": "Czy chcesz usunąć ten klucz API? Nie można tego cofnąć.", "deleteKeyConfirmation": "Czy chcesz usunąć ten klucz API? Nie można tego cofnąć.",
"deleteKeyConfirmationTitle": "Usunąć Klucz API ${keyId}?", "deleteKeyConfirmationTitle": "Usunąć Klucz API ${keyId}?",
"fullAccess": "Pełny dostęp",
"getToken": "Zdobądź token", "getToken": "Zdobądź token",
"name": "Nazwa", "name": "Nazwa",
"nameDesc": "Jak chcesz nazwać ten klucz API? ", "nameDesc": "Jak chcesz nazwać ten klucz API? ",
@ -204,6 +205,7 @@
"not-downloaded": "Nie możemy znaleść twojego pliku serwera. Czy skończył się pobierać? Czy permisje są ustawione na wykonywanle?", "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.", "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 ", "privMsg": "i także ",
"return": "Powrót do panelu",
"serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź", "serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź",
"serverJars2": "dla najnowzsych informacji.", "serverJars2": "dla najnowzsych informacji.",
"start-error": "Serwer {} nie mógł się odpalić z powodu: {}", "start-error": "Serwer {} nie mógł się odpalić z powodu: {}",

View File

@ -20,6 +20,7 @@
"created": "สร้างเมื่อ", "created": "สร้างเมื่อ",
"deleteKeyConfirmation": "คุณต้องการลบคีย์ API นี้หรือไม่ สิ่งนี้ไม่สามารถยกเลิกได้", "deleteKeyConfirmation": "คุณต้องการลบคีย์ API นี้หรือไม่ สิ่งนี้ไม่สามารถยกเลิกได้",
"deleteKeyConfirmationTitle": "ลบคีย์ API นี้ ${keyId} หรือไม่?", "deleteKeyConfirmationTitle": "ลบคีย์ API นี้ ${keyId} หรือไม่?",
"fullAccess": "เข้าถึงได้ทั้งหมด",
"getToken": "แสดงโทเค็น", "getToken": "แสดงโทเค็น",
"name": "ชื่อ", "name": "ชื่อ",
"nameDesc": "คุณต้องการเรียกโทเค็น API นี้ว่าอะไร ? ", "nameDesc": "คุณต้องการเรียกโทเค็น API นี้ว่าอะไร ? ",
@ -204,6 +205,7 @@
"not-downloaded": "ดูเหมือนว่าเราจะไม่พบแฟ้มกระทำการของคุณ (.jar) ตรวจสอบให้แน่ใจว่าการดาวโหลดน์เสร็จสิ้นแล้ว, การอนุญาตถูกตั้งไปยังแฟ้มกระทำการหรือไม่?", "not-downloaded": "ดูเหมือนว่าเราจะไม่พบแฟ้มกระทำการของคุณ (.jar) ตรวจสอบให้แน่ใจว่าการดาวโหลดน์เสร็จสิ้นแล้ว, การอนุญาตถูกตั้งไปยังแฟ้มกระทำการหรือไม่?",
"portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล", "portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล",
"privMsg": "และ ", "privMsg": "และ ",
"return": "ย้อนกลับไปยังแผงควบคุม",
"serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ", "serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ",
"serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด", "serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด",
"start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}", "start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",

View File

@ -20,6 +20,7 @@
"created": "Oluşturuldu", "created": "Oluşturuldu",
"deleteKeyConfirmation": "Bu API anahtarını silmek istediğine emin misin? Bu geri alınamaz.", "deleteKeyConfirmation": "Bu API anahtarını silmek istediğine emin misin? Bu geri alınamaz.",
"deleteKeyConfirmationTitle": "${keyId} API anahtarını kaldırma işlemi.", "deleteKeyConfirmationTitle": "${keyId} API anahtarını kaldırma işlemi.",
"fullAccess": "Tam Erişim",
"getToken": "Bir Token Al", "getToken": "Bir Token Al",
"name": "Ad", "name": "Ad",
"nameDesc": "Bu API tokeninin adı ne olsun?", "nameDesc": "Bu API tokeninin adı ne olsun?",
@ -204,6 +205,7 @@
"not-downloaded": "Çalıştırılabilir dosyanızı bulamıyoruz. İndirme işlemi tamamlandı mı? İzinler çalıştırılabilir olarak ayarlandı mı?", "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.", "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 ", "privMsg": "ve ",
"return": "Arayüze Geri Dön",
"serverJars1": "Sunucu JARs API'ına erişilemiyor.", "serverJars1": "Sunucu JARs API'ına erişilemiyor.",
"serverJars2": "en güncel bilgilere sahiptir", "serverJars2": "en güncel bilgilere sahiptir",
"start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}", "start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}",

View File

@ -20,6 +20,7 @@
"created": "Створений", "created": "Створений",
"deleteKeyConfirmation": "Ви дійсно бажаєте видалити API ключ? Це незворотня дія.", "deleteKeyConfirmation": "Ви дійсно бажаєте видалити API ключ? Це незворотня дія.",
"deleteKeyConfirmationTitle": "Видалення API ключ ${keyId}?", "deleteKeyConfirmationTitle": "Видалення API ключ ${keyId}?",
"fullAccess": "Повний доступ",
"getToken": "Отримати Токен", "getToken": "Отримати Токен",
"name": "Ім'я", "name": "Ім'я",
"nameDesc": "Як ви хочете назвати даний API токен?", "nameDesc": "Як ви хочете назвати даний API токен?",
@ -204,6 +205,7 @@
"not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?", "not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?",
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.", "portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
"privMsg": "і ", "privMsg": "і ",
"return": "Повернутись до панелі",
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте", "serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
"serverJars2": "для найактуальнішої інформації.", "serverJars2": "для найактуальнішої інформації.",
"start-error": "Сервер {} не запустився через помилку: {}", "start-error": "Сервер {} не запустився через помилку: {}",

View File

@ -20,6 +20,7 @@
"created": "创建时间", "created": "创建时间",
"deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。", "deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。",
"deleteKeyConfirmationTitle": "删除 API 密钥 ${keyId}", "deleteKeyConfirmationTitle": "删除 API 密钥 ${keyId}",
"fullAccess": "完全访问",
"getToken": "获得一个令牌", "getToken": "获得一个令牌",
"name": "名称", "name": "名称",
"nameDesc": "你想把这个 API 令牌叫做什么?", "nameDesc": "你想把这个 API 令牌叫做什么?",
@ -204,6 +205,7 @@
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?", "not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。", "portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
"privMsg": "以及", "privMsg": "以及",
"return": "返回仪表板",
"serverJars1": "无法访问服务器 JAR API。请检查", "serverJars1": "无法访问服务器 JAR API。请检查",
"serverJars2": "以获取最新信息。", "serverJars2": "以获取最新信息。",
"start-error": "服务器 {} 启动失败,错误代码为:{}", "start-error": "服务器 {} 启动失败,错误代码为:{}",