mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 15:27:17 +00:00
add create user parser
This commit is contained in:
parent
3ee5f7f13e
commit
3e044fd006
@ -30,6 +30,8 @@ from ahriman.models.sign_settings import SignSettings
|
||||
|
||||
|
||||
# pylint thinks it is bad idea, but get the fuck off
|
||||
from ahriman.models.user_access import UserAccess
|
||||
|
||||
SubParserAction = argparse._SubParsersAction # pylint: disable=protected-access
|
||||
|
||||
|
||||
@ -61,6 +63,7 @@ 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)
|
||||
@ -138,6 +141,30 @@ 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("-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
|
||||
|
@ -21,6 +21,7 @@ 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
|
||||
|
79
src/ahriman/application/handlers/create_user.py
Normal file
79
src/ahriman/application/handlers/create_user.py
Normal file
@ -0,0 +1,79 @@
|
||||
#
|
||||
# Copyright (c) 2021 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import argparse
|
||||
import configparser
|
||||
|
||||
from getpass import getpass
|
||||
from pathlib import Path
|
||||
from typing import Type
|
||||
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.user import User
|
||||
|
||||
|
||||
class CreateUser(Handler):
|
||||
"""
|
||||
create user handler
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
:param args: command line args
|
||||
:param architecture: repository architecture
|
||||
:param configuration: configuration instance
|
||||
"""
|
||||
user = CreateUser.create_user(args, configuration)
|
||||
CreateUser.create_configuration(user, configuration.include)
|
||||
|
||||
@staticmethod
|
||||
def create_configuration(user: User, include_path: Path) -> None:
|
||||
"""
|
||||
put new user to configuration
|
||||
:param user: user descriptor
|
||||
:param include_path: path to directory with configuration includes
|
||||
"""
|
||||
target = include_path / "auth.ini"
|
||||
|
||||
configuration = configparser.ConfigParser()
|
||||
configuration.read(target)
|
||||
|
||||
section = Configuration.section_name("auth", user.access.value)
|
||||
configuration.add_section(section)
|
||||
configuration.set(section, user.username, user.password)
|
||||
|
||||
with target.open("w") as ahriman_configuration:
|
||||
configuration.write(ahriman_configuration)
|
||||
|
||||
@staticmethod
|
||||
def create_user(args: argparse.Namespace, configuration: Configuration) -> User:
|
||||
"""
|
||||
create user descriptor from arguments
|
||||
:param args: command line args
|
||||
:param configuration: configuration instance
|
||||
:return: built user descriptor
|
||||
"""
|
||||
user = User(args.username, args.password, args.role)
|
||||
if user.password is None:
|
||||
user.password = getpass()
|
||||
user.password = user.generate_password(user.password, configuration.get("auth", "salt"))
|
||||
return user
|
@ -49,7 +49,9 @@ class WebClient(Client):
|
||||
self.user = User.from_option(
|
||||
configuration.get("web", "username", fallback=None),
|
||||
configuration.get("web", "password", fallback=None))
|
||||
|
||||
self.__session = requests.session()
|
||||
self.login()
|
||||
|
||||
@property
|
||||
def _ahriman_url(self) -> str:
|
||||
|
@ -38,6 +38,8 @@ class User:
|
||||
password: str
|
||||
access: UserAccess
|
||||
|
||||
_HASHER = sha512_crypt
|
||||
|
||||
@classmethod
|
||||
def from_option(cls: Type[User], username: Optional[str], password: Optional[str]) -> Optional[User]:
|
||||
"""
|
||||
@ -57,9 +59,19 @@ class User:
|
||||
:param salt: salt for hashed password
|
||||
:return: True in case if password matches, False otherwise
|
||||
"""
|
||||
verified: bool = sha512_crypt.verify(password + salt, self.password)
|
||||
verified: bool = self._HASHER.verify(password + salt, self.password)
|
||||
return verified
|
||||
|
||||
def generate_password(self, password: str, salt: str) -> str:
|
||||
"""
|
||||
generate hashed password from plain text
|
||||
:param password: entered password
|
||||
:param salt: salt for hashed password
|
||||
:return: hashed string to store in configuration
|
||||
"""
|
||||
password_hash: str = self._HASHER.hash(password + salt)
|
||||
return password_hash
|
||||
|
||||
def verify_access(self, required: UserAccess) -> bool:
|
||||
"""
|
||||
validate if user has access to requested resource
|
||||
|
@ -44,6 +44,7 @@ def client() -> Client:
|
||||
def web_client(configuration: Configuration) -> WebClient:
|
||||
"""
|
||||
fixture for web client
|
||||
:param configuration: configuration fixture
|
||||
:return: web client test instance
|
||||
"""
|
||||
configuration.set("web", "port", 8080)
|
||||
|
Loading…
Reference in New Issue
Block a user