mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
add some interface decorators and types on user and log view
This commit is contained in:
parent
e7a2e386a7
commit
c118383a1c
2 changed files with 102 additions and 24 deletions
29
src/log.py
29
src/log.py
|
@ -30,12 +30,14 @@ from io import IOBase
|
||||||
|
|
||||||
from moulinette import m18n, Moulinette
|
from moulinette import m18n, Moulinette
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
|
from yunohost.interface import Interface, InterfaceKind
|
||||||
from yunohost.utils.error import YunohostError, YunohostValidationError
|
from yunohost.utils.error import YunohostError, YunohostValidationError
|
||||||
from yunohost.utils.system import get_ynh_package_version
|
from yunohost.utils.system import get_ynh_package_version
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_file, read_yaml
|
from moulinette.utils.filesystem import read_file, read_yaml
|
||||||
|
|
||||||
logger = getActionLogger("yunohost.log")
|
logger = getActionLogger("yunohost.log")
|
||||||
|
log = Interface(name="log", help="Manage debug logs", prefix="/logs")
|
||||||
|
|
||||||
CATEGORIES_PATH = "/var/log/yunohost/categories/"
|
CATEGORIES_PATH = "/var/log/yunohost/categories/"
|
||||||
OPERATIONS_PATH = "/var/log/yunohost/categories/operation/"
|
OPERATIONS_PATH = "/var/log/yunohost/categories/operation/"
|
||||||
|
@ -67,7 +69,13 @@ BORING_LOG_LINES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def log_list(limit=None, with_details=False, with_suboperations=False):
|
@log.api("")
|
||||||
|
@log.cli("list")
|
||||||
|
def log_list(
|
||||||
|
limit: int = 50,
|
||||||
|
with_details: bool = False,
|
||||||
|
with_suboperations: bool = False,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
List available logs
|
List available logs
|
||||||
|
|
||||||
|
@ -159,8 +167,21 @@ def log_list(limit=None, with_details=False, with_suboperations=False):
|
||||||
return {"operation": operations}
|
return {"operation": operations}
|
||||||
|
|
||||||
|
|
||||||
|
@log.api("/{path:path}/share")
|
||||||
|
@log.cli("share {path}")
|
||||||
|
def log_share(path: str):
|
||||||
|
return log_show(path, share=True)
|
||||||
|
|
||||||
|
|
||||||
|
@log(share={"deprecated": True})
|
||||||
|
@log.api("/{path:path}")
|
||||||
|
@log.cli("show {path}")
|
||||||
def log_show(
|
def log_show(
|
||||||
path, number=None, share=False, filter_irrelevant=False, with_suboperations=False
|
path: str,
|
||||||
|
number: int = 50,
|
||||||
|
share: bool = False,
|
||||||
|
filter_irrelevant: bool = False,
|
||||||
|
with_suboperations: bool = False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Display a log file enriched with metadata if any.
|
Display a log file enriched with metadata if any.
|
||||||
|
@ -317,10 +338,6 @@ def log_show(
|
||||||
return infos
|
return infos
|
||||||
|
|
||||||
|
|
||||||
def log_share(path):
|
|
||||||
return log_show(path, share=True)
|
|
||||||
|
|
||||||
|
|
||||||
def is_unit_operation(
|
def is_unit_operation(
|
||||||
entities=["app", "domain", "group", "service", "user"],
|
entities=["app", "domain", "group", "service", "user"],
|
||||||
exclude=["password"],
|
exclude=["password"],
|
||||||
|
|
97
src/user.py
97
src/user.py
|
@ -26,16 +26,24 @@ import string
|
||||||
import subprocess
|
import subprocess
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from moulinette import Moulinette, m18n
|
from moulinette import Moulinette, m18n
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.process import check_output
|
from moulinette.utils.process import check_output
|
||||||
|
|
||||||
|
from yunohost.interface import Interface, InterfaceKind
|
||||||
from yunohost.utils.error import YunohostError, YunohostValidationError
|
from yunohost.utils.error import YunohostError, YunohostValidationError
|
||||||
from yunohost.service import service_status
|
from yunohost.service import service_status
|
||||||
from yunohost.log import is_unit_operation
|
from yunohost.log import is_unit_operation
|
||||||
from yunohost.utils.system import binary_to_human
|
from yunohost.utils.system import binary_to_human
|
||||||
|
|
||||||
logger = getActionLogger("yunohost.user")
|
logger = getActionLogger("yunohost.user")
|
||||||
|
user = Interface(name="user", help="Manage users and groups")
|
||||||
|
group = Interface(name="group", help="Manage user groups", prefix="/groups")
|
||||||
|
permission = Interface(
|
||||||
|
name="permission", help="Manage permissions", prefix="/permissions"
|
||||||
|
)
|
||||||
|
|
||||||
FIELDS_FOR_IMPORT = {
|
FIELDS_FOR_IMPORT = {
|
||||||
"username": r"^[a-z0-9_]+$",
|
"username": r"^[a-z0-9_]+$",
|
||||||
|
@ -52,7 +60,15 @@ FIELDS_FOR_IMPORT = {
|
||||||
ADMIN_ALIASES = ["root", "admin", "admins", "webmaster", "postmaster", "abuse"]
|
ADMIN_ALIASES = ["root", "admin", "admins", "webmaster", "postmaster", "abuse"]
|
||||||
|
|
||||||
|
|
||||||
def user_list(fields=None):
|
@user.api("/list")
|
||||||
|
@user.cli("list")
|
||||||
|
def user_list(fields: list[str] = ["username", "fullname", "mail", "mailbox-quota"]):
|
||||||
|
"""
|
||||||
|
List users
|
||||||
|
|
||||||
|
\b
|
||||||
|
- **fields**: a list of fields to fetch per user. Available attributes: `username`, `password`, `fullname`, `firstname`, `lastname`, `mail`, `mail-alias`, `mail-forward`, `mailbox-quota`, `groups`, `shell`, `home-path`.
|
||||||
|
"""
|
||||||
|
|
||||||
from yunohost.utils.ldap import _get_ldap_interface
|
from yunohost.utils.ldap import _get_ldap_interface
|
||||||
|
|
||||||
|
@ -123,19 +139,46 @@ def user_list(fields=None):
|
||||||
return {"users": users}
|
return {"users": users}
|
||||||
|
|
||||||
|
|
||||||
|
@user(
|
||||||
|
private=["from_import"],
|
||||||
|
username={"pattern": "^[a-z0-9_]+$"},
|
||||||
|
firstname={"deprecated": True},
|
||||||
|
lastname={"deprecated": True},
|
||||||
|
)
|
||||||
|
@user.api("/create", method="post", as_body=True)
|
||||||
|
@user.cli(
|
||||||
|
"create {username}",
|
||||||
|
domain={"prompt": True},
|
||||||
|
password={"prompt": True},
|
||||||
|
fullname={"prompt": True},
|
||||||
|
)
|
||||||
@is_unit_operation([("username", "user")])
|
@is_unit_operation([("username", "user")])
|
||||||
def user_create(
|
def user_create(
|
||||||
operation_logger,
|
operation_logger,
|
||||||
username,
|
username: str,
|
||||||
domain,
|
domain: str,
|
||||||
password,
|
password: str,
|
||||||
fullname=None,
|
fullname: Optional[str] = None,
|
||||||
firstname=None,
|
mailbox_quota: str = "0",
|
||||||
lastname=None,
|
admin: bool = False,
|
||||||
mailbox_quota="0",
|
firstname: Optional[str] = None,
|
||||||
admin=False,
|
lastname: Optional[str] = None,
|
||||||
from_import=False,
|
from_import: bool = False,
|
||||||
):
|
):
|
||||||
|
"""
|
||||||
|
Create user
|
||||||
|
\b
|
||||||
|
- **username**: The unique username to create
|
||||||
|
- **domain**: Domain for the email address and xmpp account
|
||||||
|
- **password**: User password
|
||||||
|
- **fullname**: The full name of the user
|
||||||
|
- **mailbox_quota**: Mailbox size quota
|
||||||
|
- **admin**: Add in adrmin group
|
||||||
|
- **firstname**: Deprecated. Use `--fullname` instead.
|
||||||
|
- **lastname**: Deprecated. Use `--fullname` instead.
|
||||||
|
\f
|
||||||
|
- **from_import**:
|
||||||
|
"""
|
||||||
|
|
||||||
if firstname or lastname:
|
if firstname or lastname:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
@ -171,19 +214,19 @@ def user_create(
|
||||||
assert_password_is_strong_enough("admin" if admin else "user", password)
|
assert_password_is_strong_enough("admin" if admin else "user", password)
|
||||||
|
|
||||||
# Validate domain used for email address/xmpp account
|
# Validate domain used for email address/xmpp account
|
||||||
if domain is None:
|
if not domain:
|
||||||
if Moulinette.interface.type == "api":
|
if Interface.kind is InterfaceKind.API:
|
||||||
raise YunohostValidationError(
|
raise YunohostValidationError(
|
||||||
"Invalid usage, you should specify a domain argument"
|
"Invalid usage, you should specify a domain argument"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# On affiche les differents domaines possibles
|
# On affiche les differents domaines possibles
|
||||||
Moulinette.display(m18n.n("domains_available"))
|
Interface.display(m18n.n("domains_available"))
|
||||||
for domain in domain_list()["domains"]:
|
for domain in domain_list()["domains"]:
|
||||||
Moulinette.display(f"- {domain}")
|
Interface.display(f"- {domain}")
|
||||||
|
|
||||||
maindomain = _get_maindomain()
|
maindomain = _get_maindomain()
|
||||||
domain = Moulinette.prompt(
|
domain = Interface.prompt(
|
||||||
m18n.n("ask_user_domain") + f" (default: {maindomain})"
|
m18n.n("ask_user_domain") + f" (default: {maindomain})"
|
||||||
)
|
)
|
||||||
if not domain:
|
if not domain:
|
||||||
|
@ -663,8 +706,13 @@ def user_export():
|
||||||
return body
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
@user(csvfile={"file": True})
|
||||||
|
@user.api("/import", method="post")
|
||||||
|
@user.cli("import")
|
||||||
@is_unit_operation()
|
@is_unit_operation()
|
||||||
def user_import(operation_logger, csvfile, update=False, delete=False):
|
def user_import(
|
||||||
|
operation_logger, csvfile: str, update: bool = False, delete: bool = False
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Import users from CSV
|
Import users from CSV
|
||||||
|
|
||||||
|
@ -1274,6 +1322,8 @@ def user_group_update(
|
||||||
return user_group_info(groupname)
|
return user_group_info(groupname)
|
||||||
|
|
||||||
|
|
||||||
|
@group.api("/{groupname}")
|
||||||
|
@group.cli("info {groupname}")
|
||||||
def user_group_info(groupname):
|
def user_group_info(groupname):
|
||||||
"""
|
"""
|
||||||
Get user informations
|
Get user informations
|
||||||
|
@ -1310,7 +1360,12 @@ def user_group_info(groupname):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def user_group_add(groupname, usernames, force=False, sync_perm=True):
|
@group(private=["force", "sync_perm"])
|
||||||
|
@group.api("/{groupname}/add", method="put")
|
||||||
|
@group.cli("add {groupname} {usernames}")
|
||||||
|
def user_group_add(
|
||||||
|
groupname: str, usernames: list[str], force: bool = False, sync_perm: bool = True
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Add user(s) to a group
|
Add user(s) to a group
|
||||||
|
|
||||||
|
@ -1349,7 +1404,13 @@ def user_group_remove_mailalias(groupname, aliases):
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
def user_permission_list(short=False, full=False, apps=[]):
|
@permission.api("/")
|
||||||
|
@permission.cli("list {apps}")
|
||||||
|
def user_permission_list(
|
||||||
|
apps: Optional[list[str]] = None,
|
||||||
|
short: bool = False,
|
||||||
|
full: bool = False,
|
||||||
|
):
|
||||||
from yunohost.permission import user_permission_list
|
from yunohost.permission import user_permission_list
|
||||||
|
|
||||||
return user_permission_list(short, full, absolute_urls=True, apps=apps)
|
return user_permission_list(short, full, absolute_urls=True, apps=apps)
|
||||||
|
|
Loading…
Add table
Reference in a new issue