add ability to remove an user

also replace old user by new one before creation
This commit is contained in:
2021-09-16 02:36:53 +03:00
parent b561bcc25d
commit 0cf7756ec4
6 changed files with 316 additions and 231 deletions

View File

@ -62,7 +62,6 @@ def _parser() -> argparse.ArgumentParser:
_set_check_parser(subparsers)
_set_clean_parser(subparsers)
_set_config_parser(subparsers)
_set_create_user_parser(subparsers)
_set_init_parser(subparsers)
_set_key_import_parser(subparsers)
_set_rebuild_parser(subparsers)
@ -76,6 +75,7 @@ def _parser() -> argparse.ArgumentParser:
_set_status_update_parser(subparsers)
_set_sync_parser(subparsers)
_set_update_parser(subparsers)
_set_user_parser(subparsers)
_set_web_parser(subparsers)
return parser
@ -141,31 +141,6 @@ def _set_config_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser
def _set_create_user_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for create user subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser(
"create-user",
help="create user for web services",
description="create user for web services with password and role. In case if password was not entered it will be asked interactively",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("username", help="username for web service")
parser.add_argument("--as-service", help="add user as service user", action="store_true")
parser.add_argument("-r", "--role", help="user role", type=UserAccess, choices=UserAccess, default=UserAccess.Read)
parser.add_argument("-p", "--password", help="user password")
parser.set_defaults(
handler=handlers.CreateUser,
architecture=[""],
lock=None,
no_log=True,
no_report=True,
unsafe=True)
return parser
def _set_init_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for init subcommand
@ -359,6 +334,32 @@ def _set_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser
def _set_user_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for create user subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser(
"user",
help="manage users for web services",
description="manage users for web services with password and role. In case if password was not entered it will be asked interactively",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("username", help="username for web service")
parser.add_argument("--as-service", help="add user as service user", action="store_true")
parser.add_argument(
"-a",
"--access",
help="user access level",
type=UserAccess,
choices=UserAccess,
default=UserAccess.Read)
parser.add_argument("-p", "--password", help="user password")
parser.add_argument("-r", "--remove", help="remove user from configuration", action="store_true")
parser.set_defaults(handler=handlers.User, architecture=[""], lock=None, no_log=True, no_report=True, unsafe=True)
return parser
def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for web subcommand

View File

@ -21,7 +21,6 @@ from ahriman.application.handlers.handler import Handler
from ahriman.application.handlers.add import Add
from ahriman.application.handlers.clean import Clean
from ahriman.application.handlers.create_user import CreateUser
from ahriman.application.handlers.dump import Dump
from ahriman.application.handlers.init import Init
from ahriman.application.handlers.key_import import KeyImport
@ -36,4 +35,5 @@ from ahriman.application.handlers.status import Status
from ahriman.application.handlers.status_update import StatusUpdate
from ahriman.application.handlers.sync import Sync
from ahriman.application.handlers.update import Update
from ahriman.application.handlers.user import User
from ahriman.application.handlers.web import Web

View File

@ -25,12 +25,13 @@ from typing import Type
from ahriman.application.handlers.handler import Handler
from ahriman.core.configuration import Configuration
from ahriman.models.user import User
from ahriman.models.user import User as MUser
from ahriman.models.user_access import UserAccess
class CreateUser(Handler):
class User(Handler):
"""
create user handler
user management handler
"""
@classmethod
@ -43,13 +44,30 @@ class CreateUser(Handler):
:param configuration: configuration instance
:param no_report: force disable reporting
"""
salt = CreateUser.get_salt(configuration)
user = CreateUser.create_user(args)
auth_configuration = CreateUser.get_auth_configuration(configuration.include)
CreateUser.create_configuration(auth_configuration, user, salt, args.as_service)
salt = User.get_salt(configuration)
user = User.create_user(args)
auth_configuration = User.get_auth_configuration(configuration.include)
User.clear_user(auth_configuration, user)
if not args.remove:
User.create_configuration(auth_configuration, user, salt, args.as_service)
User.write_configuration(configuration)
@staticmethod
def create_configuration(configuration: Configuration, user: User, salt: str, as_service_user: bool) -> None:
def clear_user(configuration: Configuration, user: MUser) -> None:
"""
remove user user from configuration file in case if it exists
:param configuration: configuration instance
:param user: user descriptor
"""
for role in UserAccess:
section = Configuration.section_name("auth", role.value)
if not configuration.has_option(section, user.username):
continue
configuration.remove_option(section, user.username)
@staticmethod
def create_configuration(configuration: Configuration, user: MUser, salt: str, as_service_user: bool) -> None:
"""
put new user to configuration
:param configuration: configuration instance
@ -65,19 +83,14 @@ class CreateUser(Handler):
configuration.set_option("web", "username", user.username)
configuration.set_option("web", "password", user.password)
if configuration.path is None:
return
with configuration.path.open("w") as ahriman_configuration:
configuration.write(ahriman_configuration)
@staticmethod
def create_user(args: argparse.Namespace) -> User:
def create_user(args: argparse.Namespace) -> MUser:
"""
create user descriptor from arguments
:param args: command line args
:return: built user descriptor
"""
user = User(args.username, args.password, args.role)
user = MUser(args.username, args.password, args.access)
if user.password is None:
user.password = getpass.getpass()
return user
@ -91,8 +104,7 @@ class CreateUser(Handler):
"""
target = include_path / "auth.ini"
configuration = Configuration()
if target.is_file(): # load current configuration in case if it exists
configuration.load(target)
configuration.load(target)
return configuration
@ -107,4 +119,16 @@ class CreateUser(Handler):
salt = configuration.get("auth", "salt", fallback=None)
if salt:
return salt
return User.generate_password(salt_length)
return MUser.generate_password(salt_length)
@staticmethod
def write_configuration(configuration: Configuration) -> None:
"""
write configuration file
:param configuration: configuration instance
"""
if configuration.path is None:
return # should never happen actually
with configuration.path.open("w") as ahriman_configuration:
configuration.write(ahriman_configuration)
configuration.path.chmod(0o600)