Source code for aiida.cmdline.commands.user

# -*- coding: utf-8 -*-
###########################################################################
# Copyright (c), The AiiDA team. All rights reserved.                     #
# This file is part of the AiiDA code.                                    #
#                                                                         #
# The code is hosted on GitHub at https://github.com/aiidateam/aiida_core #
# For further information on the license, see the LICENSE.txt file        #
# For further information please visit http://www.aiida.net               #
###########################################################################
"""
This allows to setup and configure a user from command line.
"""
import sys

import click

from aiida.backends.utils import load_dbenv, is_dbenv_loaded
from aiida.cmdline.baseclass import VerdiCommandWithSubcommands
from aiida.cmdline.commands import user, verdi
from aiida.control.user import get_or_new_user

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])


[docs]class User(VerdiCommandWithSubcommands): """ List and configure new AiiDA users. Allow to see the list of AiiDA users, their permissions, and to configure old and new users. """
[docs] def __init__(self): """ A dictionary with valid commands and functions to be called. """ self.valid_subcommands = { 'configure': (self.cli, self.complete_emails), 'list': (self.cli, self.complete_none), }
[docs] def cli(self, *args): verdi()
[docs] def complete_emails(self, subargs_idx, subargs): load_dbenv() from aiida.backends.djsite.db import models emails = models.DbUser.objects.all().values_list('email', flat=True) return "\n".join(emails)
[docs]def do_configure(email, first_name, last_name, institution, no_password, non_interactive=False, force=False, **kwargs): if not is_dbenv_loaded(): load_dbenv() from aiida.orm import User as UserModel import readline import getpass configure_user = False user, created = get_or_new_user(email=email) if not created: click.echo("\nAn AiiDA user for email '{}' is already present " "in the DB:".format(email)) if not non_interactive: reply = click.confirm("Do you want to reconfigure it?") if reply: configure_user = True elif force: configure_user = True else: configure_user = True click.echo("Configuring a new user with email '{}'".format(email)) if configure_user: if not non_interactive: try: attributes = {} for field in UserModel.REQUIRED_FIELDS: verbose_name = field.capitalize() readline.set_startup_hook(lambda: readline.insert_text( getattr(user, field))) if field == 'first_name' and first_name: attributes[field] = first_name elif field == 'last_name' and last_name: attributes[field] = last_name elif field == 'institution' and institution: attributes[field] = institution else: attributes[field] = raw_input('{}: '.format(verbose_name)) finally: readline.set_startup_hook(lambda: readline.insert_text("")) else: attributes = kwargs.copy() attributes['first_name'] = first_name attributes['last_name'] = last_name attributes['institution'] = institution for k, v in attributes.iteritems(): setattr(user, k, v) change_password = False if no_password: user.password = None else: if user.has_usable_password(): reply = raw_input("Do you want to replace the user password? [y/N] ") reply = reply.strip() if not reply: pass elif reply.lower() == 'n': pass elif reply.lower() == 'y': change_password = True else: click.echo("Invalid answer, assuming answer was 'NO'") else: reply = raw_input("The user has no password, do you want to set one? [y/N] ") reply = reply.strip() if not reply: pass elif reply.lower() == 'n': pass elif reply.lower() == 'y': change_password = True else: click.echo("Invalid answer, assuming answer was 'NO'") if change_password: match = False while not match: new_password = getpass.getpass("Insert the new password: ") new_password_check = getpass.getpass( "Insert the new password (again): ") if new_password == new_password_check: match = True else: click.echo("ERROR, the two passwords do not match.") ## Set the password here user.password = new_password else: user.password = None user.force_save() click.echo(">> User {} {} saved. <<".format(user.first_name, user.last_name)) if not user.has_usable_password(): click.echo("** NOTE: no password set for this user, ") click.echo(" so he/she will not be able to login") click.echo(" via the REST API and the Web Interface.")
@user.command(context_settings=CONTEXT_SETTINGS) @click.argument('email', type=str) @click.option('--first-name', prompt='First Name', type=str) @click.option('--last-name', prompt='Last Name', type=str) @click.option('--institution', prompt='Institution', type=str) @click.option('--no-password', is_flag=True) @click.option('--force-reconfigure', is_flag=True) def configure(email, first_name, last_name, institution, no_password, force_reconfigure): do_configure(email=email, first_name=first_name, last_name=last_name, institution=institution, no_password=no_password, force_reconfigure=force_reconfigure) @user.command() @click.option('--color', is_flag=True, help='Show results with colors', default=False) def list(color): if not is_dbenv_loaded(): load_dbenv() from aiida.orm.implementation import User from aiida.common.utils import get_configured_user_email from aiida.common.exceptions import ConfigurationError try: current_user = get_configured_user_email() except ConfigurationError: current_user = None if current_user is not None: pass else: click.echo("### No default user configured yet, run 'verdi install'! ###", err=True) for user in User.get_all_users(): name_pieces = [] if user.first_name: name_pieces.append(user.first_name) if user.last_name: name_pieces.append(user.last_name) full_name = " ".join(name_pieces) if full_name: full_name = " {}".format(full_name) institution_str = " ({})".format( user.institution) if user.institution else "" color_id = 39 # Default foreground color permissions_list = [] if user.is_staff: permissions_list.append("STAFF") if user.is_superuser: permissions_list.append("SUPERUSER") if not user.has_usable_password(): permissions_list.append("NO_PWD") color_id = 90 # Dark gray else: color_id = 34 # Blue permissions_str = ",".join(permissions_list) if permissions_str: permissions_str = " [{}]".format(permissions_str) if user.email == current_user: symbol = ">" color_id = 31 else: symbol = "*" if color: start_color = "\x1b[{}m".format(color_id) end_color = "\x1b[0m" bold_sequence = "\x1b[1;{}m".format(color_id) nobold_sequence = "\x1b[0;{}m".format(color_id) else: start_color = "" end_color = "" bold_sequence = "" nobold_sequence = "" click.echo("{}{} {}{}{}:{}{}{}{}".format( start_color, symbol, bold_sequence, user.email, nobold_sequence, full_name, institution_str, permissions_str, end_color))