Source code for msl.network.cli_user

"""
Command line interface for the ``user`` command.

To see the help documentation, run the following command in a terminal::

   msl-network user --help

"""
import os

from .constants import DATABASE
from .database import UsersTable
from .utils import ensure_root_path

HELP = 'Add/remove a user into/from a database.'

DESCRIPTION = HELP + """

The Network Manager can be started with the option to use a user's login
credentials as the authorisation check for a Client or Service to be able
to connect to the Network Manager.

To use the login credentials as the authentication check, start the Network
Manager with the ``--auth-login`` flag::

  msl-network start --auth-login
  
"""

EPILOG = """
Examples::

  # add 'j.doe' to the default database  
  msl-network user add j.doe --password a good password

  # add 'a.smith' as an administrator to the database  
  msl-network user add a.smith --password !PaSsWoRd* --admin

  # update 'j.doe' to be an administrator  
  msl-network user update j.doe --admin

  # update 'a.smith' to not be an administrator  
  msl-network user update a.smith

  # update the password for 'j.doe' using a password in a file 
  msl-network user update j.doe --password /path/to/my/password.txt

  # remove 'j.doe' from the default database
  msl-network user remove j.doe

  # add 'j.doe' to a specific database 
  msl-network user add j.doe --password The Password To Use --database /path/to/database.db 

  # list all users in the database
  msl-network user list

"""

__doc__ += DESCRIPTION + EPILOG


[docs] def add_parser_user(parser): """Add the ``user`` command to the `parser`.""" p = parser.add_parser( 'user', help=HELP, description=DESCRIPTION, epilog=EPILOG, ) p.add_argument( 'action', choices=['insert', 'add', 'remove', 'delete', 'update', 'list'], help='The action to perform.' ) p.add_argument( 'username', nargs='?', help='The name of the user.' ) p.add_argument( '-a', '--admin', action='store_true', default=False, help='Pass in this flag if the user is an administrator.\n' 'To remove administrative rights for a user run the\n' '"update" command for that user without the --admin flag.' ) p.add_argument( '-d', '--database', help='The path to a database file to save the user credentials.' ) p.add_argument( '-p', '--password', nargs='+', help='The password for the user (can contain spaces). Specify\n' 'a path to a file if you do not want to type the password\n' 'in the terminal (i.e., you do not want the password to\n' 'appear in your command history). Whatever is written on\n' 'the first line in the file will be used for the password.\n' 'WARNING: If you specify a path that does not exist then the\n' 'path itself will be used as the password.' ) p.set_defaults(func=execute)
[docs] def execute(args): """Executes the ``user`` command.""" database = DATABASE if args.database is None else args.database ensure_root_path(database) db = UsersTable(database=database) if args.action == 'list': users = db.users() if not users: print('There are no users in the database') return width = len('Username') for name, _ in users: width = max(width, len(name)) print(f'Users in {db.path}\n') print('Username'.ljust(width) + ' Administrator') print('='*width + ' =============') for name, admin in users: print(f'{name.ljust(width)} {admin}') return if args.username is None: print(f'ValueError: You must specify a username to {args.action}') return password = None if args.password is None else ' '.join(args.password) if password is not None and os.path.isfile(password): print('Reading the password from the file') with open(password, mode='rt') as fp: password = fp.readline().strip() if args.action in ['insert', 'add']: try: db.insert(args.username, password, args.admin) except ValueError as e: print(f'ValueError: {e}') else: print(f'{args.username} has been {args.action}ed') elif args.action in ['remove', 'delete']: try: db.delete(args.username) except ValueError: print(f'ValueError: Cannot {args.action} {args.username!r}. ' f'This user is not in the table.') else: print(f'{args.username} has been {args.action}d') elif args.action == 'update': try: db.update(args.username, password=password, is_admin=args.admin) except ValueError as e: print(f'ValueError: {e}') else: print(f'Updated {args.username}') else: assert False, f'No action {args.action!r} is implemented'