mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into feature/jinja2-for-webhooks
This commit is contained in:
commit
95bb4bddfe
@ -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
|
||||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,13 +1,17 @@
|
|||||||
# 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))
|
||||||
|
- Fix child schedule failing to load after del parent ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/753))
|
||||||
### 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))
|
||||||
|
- Set audit logging to logfile instead of DB ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/751))
|
||||||
### 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
|
||||||
|
@ -95,9 +95,6 @@ class ManagementController:
|
|||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
# Audit_Log Methods
|
# Audit_Log Methods
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
@staticmethod
|
|
||||||
def get_activity_log():
|
|
||||||
return HelpersManagement.get_activity_log()
|
|
||||||
|
|
||||||
def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None):
|
def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None):
|
||||||
return self.management_helper.add_to_audit_log(
|
return self.management_helper.add_to_audit_log(
|
||||||
|
@ -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)
|
||||||
|
53
app/classes/logging/log_formatter.py
Normal file
53
app/classes/logging/log_formatter.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class JsonEncoderStrFallback(json.JSONEncoder):
|
||||||
|
def default(self, o):
|
||||||
|
try:
|
||||||
|
return super().default(o)
|
||||||
|
except TypeError as exc:
|
||||||
|
if "not JSON serializable" in str(exc):
|
||||||
|
return str(o)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
class JsonEncoderDatetime(JsonEncoderStrFallback):
|
||||||
|
def default(self, o):
|
||||||
|
if isinstance(o, datetime):
|
||||||
|
return o.strftime("%Y-%m-%dT%H:%M:%S%z")
|
||||||
|
|
||||||
|
return super().default(o)
|
||||||
|
|
||||||
|
|
||||||
|
class JsonFormatter(logging.Formatter):
|
||||||
|
def formatTime(self, record, datefmt=None):
|
||||||
|
"""
|
||||||
|
Override formatTime to customize the time format.
|
||||||
|
"""
|
||||||
|
timestamp = datetime.fromtimestamp(record.created)
|
||||||
|
if datefmt:
|
||||||
|
# Use the specified date format
|
||||||
|
return timestamp.strftime(datefmt)
|
||||||
|
# Default date format: YYYY-MM-DD HH:MM:SS,mmm
|
||||||
|
secs = int(record.msecs)
|
||||||
|
return f"{timestamp.strftime('%Y-%m-%d %H:%M:%S')},{secs:03d}"
|
||||||
|
|
||||||
|
def format(self, record):
|
||||||
|
log_data = {
|
||||||
|
"level": record.levelname,
|
||||||
|
"time": self.formatTime(record),
|
||||||
|
"log_msg": record.getMessage(),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Filter out standard log record attributes and include only custom ones
|
||||||
|
custom_attrs = ["user_name", "user_id", "server_id", "source_ip"]
|
||||||
|
extra_attrs = {
|
||||||
|
key: value for key, value in record.__dict__.items() if key in custom_attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
# Merge extra attributes with log data
|
||||||
|
log_data.update(extra_attrs)
|
||||||
|
return json.dumps(log_data)
|
@ -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
|
||||||
|
@ -16,28 +16,10 @@ from app.classes.models.base_model import BaseModel
|
|||||||
from app.classes.models.users import HelperUsers
|
from app.classes.models.users import HelperUsers
|
||||||
from app.classes.models.servers import Servers
|
from app.classes.models.servers import Servers
|
||||||
from app.classes.models.server_permissions import PermissionsServers
|
from app.classes.models.server_permissions import PermissionsServers
|
||||||
from app.classes.shared.main_models import DatabaseShortcuts
|
|
||||||
from app.classes.shared.websocket_manager import WebSocketManager
|
from app.classes.shared.websocket_manager import WebSocketManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
auth_logger = logging.getLogger("audit_log")
|
||||||
|
|
||||||
# **********************************************************************************
|
|
||||||
# Audit_Log Class
|
|
||||||
# **********************************************************************************
|
|
||||||
class AuditLog(BaseModel):
|
|
||||||
audit_id = AutoField()
|
|
||||||
created = DateTimeField(default=datetime.datetime.now)
|
|
||||||
user_name = CharField(default="")
|
|
||||||
user_id = IntegerField(default=0, index=True)
|
|
||||||
source_ip = CharField(default="127.0.0.1")
|
|
||||||
server_id = ForeignKeyField(
|
|
||||||
Servers, backref="audit_server", null=True
|
|
||||||
) # When auditing global events, use server ID null
|
|
||||||
log_msg = TextField(default="")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
table_name = "audit_log"
|
|
||||||
|
|
||||||
|
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
@ -149,10 +131,6 @@ class HelpersManagement:
|
|||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
# Audit_Log Methods
|
# Audit_Log Methods
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
@staticmethod
|
|
||||||
def get_activity_log():
|
|
||||||
query = AuditLog.select()
|
|
||||||
return DatabaseShortcuts.return_db_rows(query)
|
|
||||||
|
|
||||||
def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None):
|
def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None):
|
||||||
logger.debug(f"Adding to audit log User:{user_id} - Message: {log_msg} ")
|
logger.debug(f"Adding to audit log User:{user_id} - Message: {log_msg} ")
|
||||||
@ -166,50 +144,28 @@ class HelpersManagement:
|
|||||||
WebSocketManager().broadcast_user(user, "notification", audit_msg)
|
WebSocketManager().broadcast_user(user, "notification", audit_msg)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error broadcasting to user {user} - {e}")
|
logger.error(f"Error broadcasting to user {user} - {e}")
|
||||||
|
auth_logger.info(
|
||||||
AuditLog.insert(
|
str(log_msg),
|
||||||
{
|
extra={
|
||||||
AuditLog.user_name: user_data["username"],
|
"user_name": user_data["username"],
|
||||||
AuditLog.user_id: user_id,
|
"user_id": user_id,
|
||||||
AuditLog.server_id: server_id,
|
"server_id": server_id,
|
||||||
AuditLog.log_msg: audit_msg,
|
"source_ip": source_ip,
|
||||||
AuditLog.source_ip: source_ip,
|
},
|
||||||
}
|
)
|
||||||
).execute()
|
|
||||||
# deletes records when there's more than 300
|
|
||||||
ordered = AuditLog.select().order_by(+AuditLog.created)
|
|
||||||
for item in ordered:
|
|
||||||
if not self.helper.get_setting("max_audit_entries"):
|
|
||||||
max_entries = 300
|
|
||||||
else:
|
|
||||||
max_entries = self.helper.get_setting("max_audit_entries")
|
|
||||||
if AuditLog.select().count() > max_entries:
|
|
||||||
AuditLog.delete().where(AuditLog.audit_id == item.audit_id).execute()
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
def add_to_audit_log_raw(self, user_name, user_id, server_id, log_msg, source_ip):
|
def add_to_audit_log_raw(self, user_name, user_id, server_id, log_msg, source_ip):
|
||||||
AuditLog.insert(
|
if isinstance(server_id, Servers) and server_id is not None:
|
||||||
{
|
server_id = server_id.server_id
|
||||||
AuditLog.user_name: user_name,
|
auth_logger.info(
|
||||||
AuditLog.user_id: user_id,
|
str(log_msg),
|
||||||
AuditLog.server_id: server_id,
|
extra={
|
||||||
AuditLog.log_msg: log_msg,
|
"user_name": user_name,
|
||||||
AuditLog.source_ip: source_ip,
|
"user_id": user_id,
|
||||||
}
|
"server_id": server_id,
|
||||||
).execute()
|
"source_ip": source_ip,
|
||||||
# deletes records when there's more than 300
|
},
|
||||||
ordered = AuditLog.select().order_by(+AuditLog.created)
|
)
|
||||||
for item in ordered:
|
|
||||||
# configurable through app/config/config.json
|
|
||||||
if not self.helper.get_setting("max_audit_entries"):
|
|
||||||
max_entries = 300
|
|
||||||
else:
|
|
||||||
max_entries = self.helper.get_setting("max_audit_entries")
|
|
||||||
if AuditLog.select().count() > max_entries:
|
|
||||||
AuditLog.delete().where(AuditLog.audit_id == item.audit_id).execute()
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_crafty_row():
|
def create_crafty_row():
|
||||||
|
@ -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 = (
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
@ -1239,9 +1239,11 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["schedule"]["interval_type"] = schedule.interval_type
|
page_data["schedule"]["interval_type"] = schedule.interval_type
|
||||||
if schedule.interval_type == "reaction":
|
if schedule.interval_type == "reaction":
|
||||||
difficulty = "reaction"
|
difficulty = "reaction"
|
||||||
page_data["parent"] = self.controller.management.get_scheduled_task(
|
page_data["parent"] = None
|
||||||
schedule.parent
|
if schedule.parent:
|
||||||
)
|
page_data["parent"] = self.controller.management.get_scheduled_task(
|
||||||
|
schedule.parent
|
||||||
|
)
|
||||||
elif schedule.cron_string == "":
|
elif schedule.cron_string == "":
|
||||||
difficulty = "basic"
|
difficulty = "basic"
|
||||||
page_data["parent"] = None
|
page_data["parent"] = None
|
||||||
@ -1358,6 +1360,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")
|
||||||
@ -1505,8 +1510,6 @@ class PanelHandler(BaseHandler):
|
|||||||
template = "panel/panel_edit_role.html"
|
template = "panel/panel_edit_role.html"
|
||||||
|
|
||||||
elif page == "activity_logs":
|
elif page == "activity_logs":
|
||||||
page_data["audit_logs"] = self.controller.management.get_activity_log()
|
|
||||||
|
|
||||||
template = "panel/activity_logs.html"
|
template = "panel/activity_logs.html"
|
||||||
|
|
||||||
elif page == "download_file":
|
elif page == "download_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"
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
from app.classes.web.base_api_handler import BaseApiHandler
|
from app.classes.web.base_api_handler import BaseApiHandler
|
||||||
|
|
||||||
|
|
||||||
@ -22,9 +24,17 @@ class ApiCraftyLogIndexHandler(BaseApiHandler):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
if log_type == "audit":
|
if log_type == "audit":
|
||||||
|
with open(
|
||||||
|
os.path.join(self.controller.project_root, "logs", "audit.log"),
|
||||||
|
"r",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
log_lines = [json.loads(line) for line in f]
|
||||||
|
rev_log_lines = log_lines[::-1]
|
||||||
|
|
||||||
return self.finish_json(
|
return self.finish_json(
|
||||||
200,
|
200,
|
||||||
{"status": "ok", "data": self.controller.management.get_activity_log()},
|
{"status": "ok", "data": rev_log_lines},
|
||||||
)
|
)
|
||||||
|
|
||||||
if log_type == "session":
|
if log_type == "session":
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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"})
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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"],
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
|
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
"auth": {
|
"auth": {
|
||||||
"format": "%(asctime)s - [AUTH] - %(levelname)s - %(message)s"
|
"format": "%(asctime)s - [AUTH] - %(levelname)s - %(message)s"
|
||||||
},
|
},
|
||||||
|
"audit": {
|
||||||
|
"()": "app.classes.logging.log_formatter.JsonFormatter"
|
||||||
|
},
|
||||||
"cmd_queue": {
|
"cmd_queue": {
|
||||||
"format": "%(asctime)s - [CMD_QUEUE] - %(levelname)s - %(message)s"
|
"format": "%(asctime)s - [CMD_QUEUE] - %(levelname)s - %(message)s"
|
||||||
}
|
}
|
||||||
@ -70,6 +73,14 @@
|
|||||||
"maxBytes": 10485760,
|
"maxBytes": 10485760,
|
||||||
"backupCount": 20,
|
"backupCount": 20,
|
||||||
"encoding": "utf8"
|
"encoding": "utf8"
|
||||||
|
},
|
||||||
|
"audit_log_handler": {
|
||||||
|
"class": "logging.handlers.RotatingFileHandler",
|
||||||
|
"formatter": "audit",
|
||||||
|
"filename": "logs/audit.log",
|
||||||
|
"maxBytes": 10485760,
|
||||||
|
"backupCount": 20,
|
||||||
|
"encoding": "utf8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"loggers": {
|
"loggers": {
|
||||||
@ -108,6 +119,12 @@
|
|||||||
"cmd_queue_file_handler"
|
"cmd_queue_file_handler"
|
||||||
],
|
],
|
||||||
"propagate": false
|
"propagate": false
|
||||||
|
},
|
||||||
|
"audit_log": {
|
||||||
|
"level": "INFO",
|
||||||
|
"handlers": [
|
||||||
|
"audit_log_handler"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,25 +36,21 @@
|
|||||||
<table class="table table-hover" id="audit_table" style="overflow: scroll;" width="100%">
|
<table class="table table-hover" id="audit_table" style="overflow: scroll;" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="rounded">
|
<tr class="rounded">
|
||||||
<td>Username</td>
|
<th>Time</th>
|
||||||
<td>Time</td>
|
<th>Username</th>
|
||||||
<td>Action</td>
|
<th>Action</th>
|
||||||
<td>Server ID</td>
|
<th>Server ID</th>
|
||||||
<td>IP</td>
|
<th>IP</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for row in data['audit_logs'] %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ row['user_name'] }}</td>
|
<td colspan="5" id="image-div" class="text-center"> <!-- Center image within table -->
|
||||||
<td>
|
<img class="img-center" id="logo-animate" src="../static/assets/images/crafty-logo-square-1024.png"
|
||||||
{{ row['created'].strftime('%Y-%m-%d %H:%M:%S') }}
|
alt="Crafty Logo, Crafty is loading" width="20%"><br><br>{{ translate('datatables',
|
||||||
|
'loadingRecords', data['lang'])}}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ row['log_msg'] }}</td>
|
|
||||||
<td>{{ row['server_id'] }}</td>
|
|
||||||
<td>{{ row['source_ip'] }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% end %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@ -79,17 +75,6 @@
|
|||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script>
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
console.log('ready for JS!')
|
|
||||||
$('#audit_table').DataTable({
|
|
||||||
'order': [1, 'desc']
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('[data-toggle="popover"]').popover();
|
$('[data-toggle="popover"]').popover();
|
||||||
@ -112,6 +97,74 @@
|
|||||||
$('.too_small').popover("hide");
|
$('.too_small').popover("hide");
|
||||||
} // New width
|
} // New width
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
console.log('ready for JS!')
|
||||||
|
// Initialize DataTables
|
||||||
|
// Load initial data
|
||||||
|
getActivity();
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateActivity(data) {
|
||||||
|
let tbody = $('#audit_table tbody');
|
||||||
|
tbody.empty(); // Clear existing rows
|
||||||
|
$.each(data, function (index, value) {
|
||||||
|
let row = $('<tr>');
|
||||||
|
row.append(`<td>${value.time}</td>`);
|
||||||
|
if (value.user_name != "system" && value.user_id != "-1") {
|
||||||
|
row.append(`<td><a href="/panel/edit_user?id=${value.user_id}">${value.user_name}</a></td>`);
|
||||||
|
} else {
|
||||||
|
row.append(`<td>${value.user_name}</td>`);
|
||||||
|
}
|
||||||
|
row.append(`<td>${value.log_msg}</td>`);
|
||||||
|
row.append(`<td>${value.server_id}</td>`);
|
||||||
|
row.append(`<td>${value.source_ip}</td>`);
|
||||||
|
tbody.append(row);
|
||||||
|
});
|
||||||
|
$('#audit_table').DataTable({
|
||||||
|
'order': [[0, 'desc']], // Sort by the first column in descending order
|
||||||
|
filter: true,
|
||||||
|
"searching": true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getActivity() {
|
||||||
|
var token = getCookie("_xsrf");
|
||||||
|
let res = await fetch(`/api/v2/crafty/logs/audit`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'X-XSRFToken': token
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let responseData = await res.json();
|
||||||
|
console.log(responseData);
|
||||||
|
if (responseData.status === "ok") {
|
||||||
|
updateActivity(responseData.data);
|
||||||
|
console.log("activity update")
|
||||||
|
} else {
|
||||||
|
bootbox.alert(responseData.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function rotateImage(degree) {
|
||||||
|
$('#logo-animate').animate({ transform: degree }, {
|
||||||
|
step: function (now, fx) {
|
||||||
|
$(this).css({
|
||||||
|
'-webkit-transform': 'rotate(' + now + 'deg)',
|
||||||
|
'-moz-transform': 'rotate(' + now + 'deg)',
|
||||||
|
'transform': 'rotate(' + now + 'deg)'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setTimeout(function () {
|
||||||
|
rotateImage(360);
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
$(document).ready(function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
rotateImage(360);
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% end %}
|
{% end %}
|
@ -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);
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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: {
|
||||||
|
@ -6,7 +6,6 @@ import logging
|
|||||||
from app.classes.shared.console import Console
|
from app.classes.shared.console import Console
|
||||||
from app.classes.shared.migration import Migrator, MigrateHistory
|
from app.classes.shared.migration import Migrator, MigrateHistory
|
||||||
from app.classes.models.management import (
|
from app.classes.models.management import (
|
||||||
AuditLog,
|
|
||||||
Webhooks,
|
Webhooks,
|
||||||
Schedules,
|
Schedules,
|
||||||
Backups,
|
Backups,
|
||||||
@ -61,17 +60,6 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
peewee.CharField(primary_key=True, default=str(uuid.uuid4())),
|
peewee.CharField(primary_key=True, default=str(uuid.uuid4())),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Changes on Audit Log Table
|
|
||||||
migrator.alter_column_type(
|
|
||||||
AuditLog,
|
|
||||||
"server_id",
|
|
||||||
peewee.ForeignKeyField(
|
|
||||||
Servers,
|
|
||||||
backref="audit_server",
|
|
||||||
null=True,
|
|
||||||
field=peewee.CharField(primary_key=True, default=str(uuid.uuid4())),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
# Changes on Webhook Table
|
# Changes on Webhook Table
|
||||||
migrator.alter_column_type(
|
migrator.alter_column_type(
|
||||||
Webhooks,
|
Webhooks,
|
||||||
@ -109,13 +97,6 @@ def rollback(migrator: Migrator, database, **kwargs):
|
|||||||
peewee.AutoField(),
|
peewee.AutoField(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Changes on Audit Log Table
|
|
||||||
migrator.alter_column_type(
|
|
||||||
AuditLog,
|
|
||||||
"server_id",
|
|
||||||
peewee.IntegerField(default=None, index=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Changes on Webhook Table
|
# Changes on Webhook Table
|
||||||
migrator.alter_column_type(
|
migrator.alter_column_type(
|
||||||
Webhooks,
|
Webhooks,
|
||||||
|
@ -6,7 +6,6 @@ import logging
|
|||||||
from app.classes.shared.console import Console
|
from app.classes.shared.console import Console
|
||||||
from app.classes.shared.migration import Migrator, MigrateHistory
|
from app.classes.shared.migration import Migrator, MigrateHistory
|
||||||
from app.classes.models.management import (
|
from app.classes.models.management import (
|
||||||
AuditLog,
|
|
||||||
Webhooks,
|
Webhooks,
|
||||||
Schedules,
|
Schedules,
|
||||||
Backups,
|
Backups,
|
||||||
@ -73,20 +72,6 @@ def migrate(migrator: Migrator, database, **kwargs):
|
|||||||
try:
|
try:
|
||||||
logger.info("Migrating Data from Int to UUID (Foreign Keys)")
|
logger.info("Migrating Data from Int to UUID (Foreign Keys)")
|
||||||
Console.info("Migrating Data from Int to UUID (Foreign Keys)")
|
Console.info("Migrating Data from Int to UUID (Foreign Keys)")
|
||||||
# Changes on Audit Log Table
|
|
||||||
for audit_log in AuditLog.select():
|
|
||||||
old_server_id = audit_log.server_id_id
|
|
||||||
if old_server_id == "0" or old_server_id is None:
|
|
||||||
server_uuid = None
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
server = Servers.get_by_id(old_server_id)
|
|
||||||
server_uuid = server.server_uuid
|
|
||||||
except:
|
|
||||||
server_uuid = old_server_id
|
|
||||||
AuditLog.update(server_id=server_uuid).where(
|
|
||||||
AuditLog.audit_id == audit_log.audit_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
# Changes on Webhooks Log Table
|
# Changes on Webhooks Log Table
|
||||||
for webhook in Webhooks.select():
|
for webhook in Webhooks.select():
|
||||||
@ -247,21 +232,6 @@ def rollback(migrator: Migrator, database, **kwargs):
|
|||||||
try:
|
try:
|
||||||
logger.info("Migrating Data from UUID to Int (Foreign Keys)")
|
logger.info("Migrating Data from UUID to Int (Foreign Keys)")
|
||||||
Console.info("Migrating Data from UUID to Int (Foreign Keys)")
|
Console.info("Migrating Data from UUID to Int (Foreign Keys)")
|
||||||
# Changes on Audit Log Table
|
|
||||||
for audit_log in AuditLog.select():
|
|
||||||
old_server_id = audit_log.server_id_id
|
|
||||||
if old_server_id is None:
|
|
||||||
new_server_id = 0
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
server = Servers.get_or_none(Servers.server_uuid == old_server_id)
|
|
||||||
new_server_id = server.server_id
|
|
||||||
except:
|
|
||||||
new_server_id = old_server_id
|
|
||||||
AuditLog.update(server_id=new_server_id).where(
|
|
||||||
AuditLog.audit_id == audit_log.audit_id
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
# Changes on Webhooks Log Table
|
# Changes on Webhooks Log Table
|
||||||
for webhook in Webhooks.select():
|
for webhook in Webhooks.select():
|
||||||
old_server_id = webhook.server_id_id
|
old_server_id = webhook.server_id_id
|
||||||
|
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.
|
||||||
|
"""
|
34
app/migrations/20240420_audit_log_drop.py
Normal file
34
app/migrations/20240420_audit_log_drop.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import peewee
|
||||||
|
import datetime
|
||||||
|
from peewee import (
|
||||||
|
AutoField,
|
||||||
|
DateTimeField,
|
||||||
|
CharField,
|
||||||
|
IntegerField,
|
||||||
|
ForeignKeyField,
|
||||||
|
TextField,
|
||||||
|
)
|
||||||
|
|
||||||
|
from app.classes.shared.server import Servers
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator, db):
|
||||||
|
migrator.drop_table("audit_log")
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator, db):
|
||||||
|
class AuditLog(peewee.Model):
|
||||||
|
audit_id = AutoField()
|
||||||
|
created = DateTimeField(default=datetime.datetime.now)
|
||||||
|
user_name = CharField(default="")
|
||||||
|
user_id = IntegerField(default=0, index=True)
|
||||||
|
source_ip = CharField(default="127.0.0.1")
|
||||||
|
server_id = ForeignKeyField(
|
||||||
|
Servers, backref="audit_server", null=True
|
||||||
|
) # When auditing global events, use server ID null
|
||||||
|
log_msg = TextField(default="")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "audit_log"
|
||||||
|
|
||||||
|
migrator.create_table(AuditLog)
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Vítejte v Crafty Controlleru"
|
"welcome": "Vítejte v Crafty Controlleru"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Načítání...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktivace řazení sloupce vzestupně",
|
"sortAscending": ": aktivace řazení sloupce vzestupně",
|
||||||
@ -218,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: {}",
|
||||||
@ -612,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"
|
||||||
@ -691,4 +694,4 @@
|
|||||||
"webhook_body": "Webhook Body",
|
"webhook_body": "Webhook Body",
|
||||||
"webhooks": "Webhooky"
|
"webhooks": "Webhooky"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Willkommen bei Crafty Controller"
|
"welcome": "Willkommen bei Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Laden...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": Aktivieren, um die Spalte aufsteigend zu sortieren",
|
"sortAscending": ": Aktivieren, um die Spalte aufsteigend zu sortieren",
|
||||||
@ -203,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",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "Webhook-Inhalt",
|
"webhook_body": "Webhook-Inhalt",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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": {
|
||||||
@ -116,6 +116,7 @@
|
|||||||
"welcome": "Welcome to Crafty Controller"
|
"welcome": "Welcome to Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Loading...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": activate to sort column ascending",
|
"sortAscending": ": activate to sort column ascending",
|
||||||
@ -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?",
|
"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: {}",
|
||||||
@ -671,4 +673,4 @@
|
|||||||
"webhook_body": "Webhook Body",
|
"webhook_body": "Webhook Body",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Bienvenido a Crafty Controller"
|
"welcome": "Bienvenido a Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Cargando...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": activar para ordenar las columnas de manera ascendente",
|
"sortAscending": ": activar para ordenar las columnas de manera ascendente",
|
||||||
@ -203,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: {}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "Cuerpo del Webhook",
|
"webhook_body": "Cuerpo del Webhook",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -100,6 +100,7 @@
|
|||||||
"welcome": "Tervetuloa Crafty Controller"
|
"welcome": "Tervetuloa Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Ladataan...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": lajittele sarake nousevasti",
|
"sortAscending": ": lajittele sarake nousevasti",
|
||||||
@ -560,4 +561,4 @@
|
|||||||
"userSettings": "Käyttäjäasetukset",
|
"userSettings": "Käyttäjäasetukset",
|
||||||
"uses": "Sallittujen käyttäkertojen määtä (-1 == Ei rajaa)"
|
"uses": "Sallittujen käyttäkertojen määtä (-1 == Ei rajaa)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 ? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Bienvenue sur Crafty Controller"
|
"welcome": "Bienvenue sur Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Chargement ...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": activer pour trier les colonnes dans l'ordre croissant",
|
"sortAscending": ": activer pour trier les colonnes dans l'ordre croissant",
|
||||||
@ -203,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 : {}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "Corps du Webhook",
|
"webhook_body": "Corps du Webhook",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -99,6 +99,7 @@
|
|||||||
"welcome": "Wolkom by Crafty Controller"
|
"welcome": "Wolkom by Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Laden...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktivearje om kolom oprinnend te sortearjen",
|
"sortAscending": ": aktivearje om kolom oprinnend te sortearjen",
|
||||||
@ -529,4 +530,4 @@
|
|||||||
"userSettings": "Brûkersynstellingen",
|
"userSettings": "Brûkersynstellingen",
|
||||||
"uses": "Oantal gebrûk tastien (-1==Gjin limyt)"
|
"uses": "Oantal gebrûk tastien (-1==Gjin limyt)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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-איך תרצו לקרוא לאסימון ה",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "ברוכים הבאים ל-פאנל קראפטי"
|
"welcome": "ברוכים הבאים ל-פאנל קראפטי"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "...טוען",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": הפעילו כדי למיין עמודות בסדר עולה",
|
"sortAscending": ": הפעילו כדי למיין עמודות בסדר עולה",
|
||||||
@ -203,6 +205,7 @@
|
|||||||
"not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?",
|
"not-downloaded": "לא הצלחנו למצוא את קובץ ההפעלה שלך. האם זה סיים להוריד? האם ההרשאות מוגדרות בשביל הפעלה?",
|
||||||
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
|
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
|
||||||
"privMsg": "וה",
|
"privMsg": "וה",
|
||||||
|
"return": "חזרה לפאנל",
|
||||||
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
|
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
|
||||||
"serverJars2": "למידע מעודכן ביותר.",
|
"serverJars2": "למידע מעודכן ביותר.",
|
||||||
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
|
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "גוף ה-Webhook",
|
"webhook_body": "גוף ה-Webhook",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -99,6 +99,7 @@
|
|||||||
"welcome": "Dobrodošli u Crafty Controller"
|
"welcome": "Dobrodošli u Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Učitavanje...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktiviraj za sortiranje stupca uzlazno",
|
"sortAscending": ": aktiviraj za sortiranje stupca uzlazno",
|
||||||
@ -529,4 +530,4 @@
|
|||||||
"userSettings": "Korisničke postavke",
|
"userSettings": "Korisničke postavke",
|
||||||
"uses": "Broj dopuštenih upotreba (-1==Bez ograničenja)"
|
"uses": "Broj dopuštenih upotreba (-1==Bez ograničenja)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -100,6 +100,7 @@
|
|||||||
"welcome": "Selamat Datang Di Crafty Controller"
|
"welcome": "Selamat Datang Di Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Loading...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktifkan untuk mengurutkan kolom menaik",
|
"sortAscending": ": aktifkan untuk mengurutkan kolom menaik",
|
||||||
@ -536,4 +537,4 @@
|
|||||||
"userSettings": "Pengaturan Pengguna",
|
"userSettings": "Pengaturan Pengguna",
|
||||||
"uses": "Jumlah penggunaan yang diizinkan (-1==No Limit)"
|
"uses": "Jumlah penggunaan yang diizinkan (-1==No Limit)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Benvenuto su Crafty Controller"
|
"welcome": "Benvenuto su Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Carico...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": attiva per ordinare le colonne in modo ascendente",
|
"sortAscending": ": attiva per ordinare le colonne in modo ascendente",
|
||||||
@ -203,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: {}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "Corpo del Webhook",
|
"webhook_body": "Corpo del Webhook",
|
||||||
"webhooks": "Webhook"
|
"webhooks": "Webhook"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "WELCOM 2 CWAFTY CONTROLLR"
|
"welcome": "WELCOM 2 CWAFTY CONTROLLR"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Loading...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": activate to sort column ascending",
|
"sortAscending": ": activate to sort column ascending",
|
||||||
@ -203,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: {}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "WEBHOOK FISH",
|
"webhook_body": "WEBHOOK FISH",
|
||||||
"webhooks": "WEBHOOKZ"
|
"webhooks": "WEBHOOKZ"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)? ",
|
||||||
@ -117,6 +118,7 @@
|
|||||||
"welcome": "Esiet sveicināts Crafty Controller"
|
"welcome": "Esiet sveicināts Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Ielādē...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktivizēt lai kārotu kolonnu augoši",
|
"sortAscending": ": aktivizēt lai kārotu kolonnu augoši",
|
||||||
@ -204,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: {}",
|
||||||
@ -673,4 +676,4 @@
|
|||||||
"webhook_body": "Webhook Saturs",
|
"webhook_body": "Webhook Saturs",
|
||||||
"webhooks": "Webhooki"
|
"webhooks": "Webhooki"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Welkom bij Crafty Controller "
|
"welcome": "Welkom bij Crafty Controller "
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Bezig met laden...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": activeren om kolom oplopend te sorteren",
|
"sortAscending": ": activeren om kolom oplopend te sorteren",
|
||||||
@ -203,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: {}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "Webhook-body",
|
"webhook_body": "Webhook-body",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -99,6 +99,7 @@
|
|||||||
"welcome": "Welkom bij Crafty Controller"
|
"welcome": "Welkom bij Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Laden...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": activeer om kolom oplopend te sorteren",
|
"sortAscending": ": activeer om kolom oplopend te sorteren",
|
||||||
@ -529,4 +530,4 @@
|
|||||||
"userSettings": "Gebruikersinstellingen",
|
"userSettings": "Gebruikersinstellingen",
|
||||||
"uses": "Aantal keer toegestaan (-1==Geen limiet)"
|
"uses": "Aantal keer toegestaan (-1==Geen limiet)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Witamy w Crafty Controller"
|
"welcome": "Witamy w Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Wczytywanie...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktywuj, aby sortować kolumny w góre",
|
"sortAscending": ": aktywuj, aby sortować kolumny w góre",
|
||||||
@ -203,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: {}",
|
||||||
@ -671,4 +674,4 @@
|
|||||||
"webhook_body": "Treść Webhooka",
|
"webhook_body": "Treść Webhooka",
|
||||||
"webhooks": "Webhooki"
|
"webhooks": "Webhooki"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -100,6 +100,7 @@
|
|||||||
"welcome": "Bem-vindo ao Crafty Controller"
|
"welcome": "Bem-vindo ao Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Carregando...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": ative para ordenar a coluna de forma ascendente",
|
"sortAscending": ": ative para ordenar a coluna de forma ascendente",
|
||||||
@ -537,4 +538,4 @@
|
|||||||
"userSettings": "Configurações do Usuário",
|
"userSettings": "Configurações do Usuário",
|
||||||
"uses": "Número de Usos Permitidos (-1==Sem Limite)"
|
"uses": "Número de Usos Permitidos (-1==Sem Limite)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 นี้ว่าอะไร ? ",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "ยินดีต้อนรับสู่ Crafty Controller"
|
"welcome": "ยินดีต้อนรับสู่ Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "กำลังโหลด...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": เปิดใช้งานเพื่อเรียงลำดับคอลัมน์จากน้อยไปมาก",
|
"sortAscending": ": เปิดใช้งานเพื่อเรียงลำดับคอลัมน์จากน้อยไปมาก",
|
||||||
@ -203,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": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",
|
||||||
@ -671,4 +674,4 @@
|
|||||||
"webhook_body": "ภายใน Webhook",
|
"webhook_body": "ภายใน Webhook",
|
||||||
"webhooks": "Webhooks"
|
"webhooks": "Webhooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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?",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Crafty Controller'a Hoşgeldiniz!"
|
"welcome": "Crafty Controller'a Hoşgeldiniz!"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Yükleniyor...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": artan sütun sıralamasını aktifleştir",
|
"sortAscending": ": artan sütun sıralamasını aktifleştir",
|
||||||
@ -203,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: {}",
|
||||||
@ -671,4 +674,4 @@
|
|||||||
"webhook_body": "Webhook Gövdesi",
|
"webhook_body": "Webhook Gövdesi",
|
||||||
"webhooks": "Webhooklar"
|
"webhooks": "Webhooklar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 токен?",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "Ласкаво просимо у Crafty Controller"
|
"welcome": "Ласкаво просимо у Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "Завантаження...",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": активуйте, щоб сортувати стовпці за зростанням",
|
"sortAscending": ": активуйте, щоб сортувати стовпці за зростанням",
|
||||||
@ -203,6 +205,7 @@
|
|||||||
"not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?",
|
"not-downloaded": "Здається, ми не можемо знайти ваш виконуваний файл. Чи завершилось завантаження? Чи встановлено дозволи на виконуваний файл?",
|
||||||
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
|
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
|
||||||
"privMsg": "і ",
|
"privMsg": "і ",
|
||||||
|
"return": "Повернутись до панелі",
|
||||||
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
||||||
"serverJars2": "для найактуальнішої інформації.",
|
"serverJars2": "для найактуальнішої інформації.",
|
||||||
"start-error": "Сервер {} не запустився через помилку: {}",
|
"start-error": "Сервер {} не запустився через помилку: {}",
|
||||||
@ -671,4 +674,4 @@
|
|||||||
"webhook_body": "Код Вебхука",
|
"webhook_body": "Код Вебхука",
|
||||||
"webhooks": "Вебхуки"
|
"webhooks": "Вебхуки"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 令牌叫做什么?",
|
||||||
@ -116,6 +117,7 @@
|
|||||||
"welcome": "欢迎来到 Crafty Controller"
|
"welcome": "欢迎来到 Crafty Controller"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
|
"loadingRecords": "正在加载……",
|
||||||
"i18n": {
|
"i18n": {
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ":激活对队列的升序排列",
|
"sortAscending": ":激活对队列的升序排列",
|
||||||
@ -203,6 +205,7 @@
|
|||||||
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
|
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
|
||||||
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
||||||
"privMsg": "以及",
|
"privMsg": "以及",
|
||||||
|
"return": "返回仪表板",
|
||||||
"serverJars1": "无法访问服务器 JAR API。请检查",
|
"serverJars1": "无法访问服务器 JAR API。请检查",
|
||||||
"serverJars2": "以获取最新信息。",
|
"serverJars2": "以获取最新信息。",
|
||||||
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
||||||
@ -672,4 +675,4 @@
|
|||||||
"webhook_body": "Webhook 消息体(Body)",
|
"webhook_body": "Webhook 消息体(Body)",
|
||||||
"webhooks": "Webhook"
|
"webhooks": "Webhook"
|
||||||
}
|
}
|
||||||
}
|
}
|
6
main.py
6
main.py
@ -17,6 +17,7 @@ from app.classes.models.users import HelperUsers
|
|||||||
from app.classes.models.management import HelpersManagement
|
from app.classes.models.management import HelpersManagement
|
||||||
from app.classes.shared.import_helper import ImportHelpers
|
from app.classes.shared.import_helper import ImportHelpers
|
||||||
from app.classes.shared.websocket_manager import WebSocketManager
|
from app.classes.shared.websocket_manager import WebSocketManager
|
||||||
|
from app.classes.logging.log_formatter import JsonFormatter
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
helper = Helpers()
|
helper = Helpers()
|
||||||
@ -284,6 +285,11 @@ def setup_logging(debug=True):
|
|||||||
|
|
||||||
logging.config.dictConfig(logging_config)
|
logging.config.dictConfig(logging_config)
|
||||||
|
|
||||||
|
# Apply JSON formatting to the "audit" handler
|
||||||
|
for handler in logging.getLogger().handlers:
|
||||||
|
if handler.name == "audit_log_handler":
|
||||||
|
handler.setFormatter(JsonFormatter())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logging.warning(f"Unable to read logging config from {logging_config_file}")
|
logging.warning(f"Unable to read logging config from {logging_config_file}")
|
||||||
|
Loading…
Reference in New Issue
Block a user