Example #1
0
def token_grant(admin_access_token, id_, email):
    """Grant a token to the selected user."""
    try:
        admin = User.query.filter_by(id_=ADMIN_USER_ID).one_or_none()
        if admin_access_token != admin.access_token:
            raise ValueError("Admin access token invalid.")
        user = _get_user_by_criteria(id_, email)
        error_msg = None
        if not user:
            error_msg = f"User {id_ or email} does not exist."
        elif user.access_token:
            error_msg = (
                f"User {user.id_} ({user.email}) has already an active access token."
            )
        if error_msg:
            click.secho(f"ERROR: {error_msg}", fg="red")
            sys.exit(1)
        if user.access_token_status in [UserTokenStatus.revoked.name, None]:
            click.confirm(
                f"User {user.id_} ({user.email}) access token status"
                f" is {user.access_token_status}, do you want to"
                " proceed?",
                abort=True,
            )

        user_granted_token = secrets.token_urlsafe(16)
        user.access_token = user_granted_token
        Session.commit()
        log_msg = (f"Token for user {user.id_} ({user.email}) granted.\n"
                   f"\nToken: {user_granted_token}")
        click.secho(log_msg, fg="green")
        admin.log_action(AuditLogAction.grant_token, {"reana_admin": log_msg})
        # send notification to user by email
        email_subject = "REANA access token granted"
        email_body = JinjaEnv.render_template(
            "emails/token_granted.txt",
            user_full_name=user.full_name,
            reana_hostname=REANA_HOSTNAME,
            ui_config=REANAConfig.load("ui"),
            sender_email=ADMIN_EMAIL,
        )
        send_email(user.email, email_subject, email_body)

    except click.exceptions.Abort:
        click.echo("Grant token aborted.")
    except REANAEmailNotificationError as e:
        click.secho(
            "Something went wrong while sending email:\n{}".format(e),
            fg="red",
            err=True,
        )
    except Exception as e:
        click.secho(
            "Something went wrong while granting token:\n{}".format(e),
            fg="red",
            err=True,
        )
Example #2
0
def set_quota_limit(ctx, admin_access_token, emails, resource_name, limit):
    """Set quota limits to the given users per resource."""
    try:
        for email in emails:
            error_msg = None
            user = _get_user_by_criteria(None, email)
            resource = Resource.query.filter_by(
                name=resource_name).one_or_none()
            if not user:
                error_msg = f"ERROR: Provided user {email} does not exist."
            elif not resource:
                error_msg = (
                    "ERROR: Provided resource name does not exist. Available "
                    f"resources are {[resource.name for resource in Resource.query]}."
                )
            if error_msg:
                click.secho(
                    error_msg,
                    fg="red",
                    err=True,
                )
                sys.exit(1)

            user_resource = UserResource.query.filter_by(
                user=user, resource=resource).one_or_none()
            if user_resource:
                user_resource.quota_limit = limit
                Session.add(user_resource)
            else:
                # Create user resource in case there isn't one. Useful for old users.
                user.resources.append(
                    UserResource(
                        user_id=user.id_,
                        resource_id=resource.id_,
                        quota_limit=limit,
                        quota_used=0,
                    ))
        Session.commit()
        click.secho(
            f"Quota limit {limit} for '{resource.name}' successfully set to users {emails}.",
            fg="green",
        )
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(
            click.style("Quota could not be set: \n{}".format(str(e)),
                        fg="red"),
            err=True,
        )
Example #3
0
def token_revoke(admin_access_token, id_, email):
    """Revoke selected user's token."""
    try:
        admin = User.query.filter_by(id_=ADMIN_USER_ID).one_or_none()
        if admin_access_token != admin.access_token:
            raise ValueError("Admin access token invalid.")
        user = _get_user_by_criteria(id_, email)

        error_msg = None
        if not user:
            error_msg = f"User {id_ or email} does not exist."
        elif not user.access_token:
            error_msg = (f"User {user.id_} ({user.email}) does not have an"
                         " active access token.")
        if error_msg:
            click.secho(f"ERROR: {error_msg}", fg="red")
            sys.exit(1)

        revoked_token = user.access_token
        user.active_token.status = UserTokenStatus.revoked
        Session.commit()
        log_msg = (f"User token {revoked_token} ({user.email}) was"
                   " successfully revoked.")
        click.secho(log_msg, fg="green")
        admin.log_action(AuditLogAction.revoke_token, {"reana_admin": log_msg})
        # send notification to user by email
        email_subject = "REANA access token revoked"
        email_body = JinjaEnv.render_template(
            "emails/token_revoked.txt",
            user_full_name=user.full_name,
            reana_hostname=REANA_HOSTNAME,
            ui_config=REANAConfig.load("ui"),
            sender_email=ADMIN_EMAIL,
        )
        send_email(user.email, email_subject, email_body)

    except REANAEmailNotificationError as e:
        click.secho(
            "Something went wrong while sending email:\n{}".format(e),
            fg="red",
            err=True,
        )
    except Exception as e:
        click.secho(
            "Something went wrong while revoking token:\n{}".format(e),
            fg="red",
            err=True,
        )
Example #4
0
def token_grant(admin_access_token, id_, email):
    """Grant a token to the selected user."""
    try:
        admin = User.query.filter_by(id_=ADMIN_USER_ID).one_or_none()
        if admin_access_token != admin.access_token:
            raise ValueError("Admin access token invalid.")
        user = _get_user_by_criteria(id_, email)
        error_msg = None
        if not user:
            error_msg = f"User {id_ or email} does not exist."
        elif user.access_token:
            error_msg = (f"User {user.id_} ({user.email}) has already an"
                         " active access token.")
        if error_msg:
            click.secho(f"ERROR: {error_msg}", fg="red")
            sys.exit(1)
        if user.access_token_status in [UserTokenStatus.revoked.name, None]:
            click.confirm(
                f"User {user.id_} ({user.email}) access token status"
                f" is {user.access_token_status}, do you want to"
                " proceed?",
                abort=True,
            )

        user_granted_token = secrets.token_urlsafe(16)
        user.access_token = user_granted_token
        Session.commit()
        log_msg = (f"Token for user {user.id_} ({user.email}) granted.\n"
                   f"\nToken: {user_granted_token}")
        click.secho(log_msg, fg="green")
        admin.log_action(AuditLogAction.grant_token, {"reana_admin": log_msg})
        # send notification to user by email
        email_subject = "REANA access token granted"
        email_body = (
            f"Dear {user.full_name},\n\nYour REANA access token has"
            f" been granted, please find it on https://{REANA_URL}/profile"
            "\n\nThe REANA support team")
        send_email(user.email, email_subject, email_body)

    except click.exceptions.Abort as e:
        click.echo("Grant token aborted.")
    except Exception as e:
        click.secho(
            "Something went wrong while granting token:\n{}".format(e),
            fg="red",
            err=True,
        )
Example #5
0
def token_revoke(admin_access_token, id_, email):
    """Revoke selected user's token."""
    try:
        admin = User.query.filter_by(id_=ADMIN_USER_ID).one_or_none()
        if admin_access_token != admin.access_token:
            raise ValueError("Admin access token invalid.")
        user = _get_user_by_criteria(id_, email)

        error_msg = None
        if not user:
            error_msg = f"User {id_ or email} does not exist."
        elif not user.access_token:
            error_msg = (f"User {user.id_} ({user.email}) does not have an"
                         " active access token.")
        if error_msg:
            click.secho(f"ERROR: {error_msg}", fg="red")
            sys.exit(1)

        revoked_token = user.access_token
        user.active_token.status = UserTokenStatus.revoked
        Session.commit()
        log_msg = (f"User token {revoked_token} ({user.email}) was"
                   " successfully revoked.")
        click.secho(log_msg, fg="green")
        admin.log_action(AuditLogAction.revoke_token, {"reana_admin": log_msg})
        # send notification to user by email
        email_subject = "REANA access token revoked"
        email_body = (f"Dear {user.full_name},\n\nYour REANA access token has"
                      " been revoked.\n\nThe REANA support team")
        send_email(user.email, email_subject, email_body)

    except Exception as e:
        click.secho(
            "Something went wrong while revoking token:\n{}".format(e),
            fg="red",
            err=True,
        )
Example #6
0
def set_quota_limit(ctx, emails, resource_type, resource_name, limit):
    """Set quota limits to the given users per resource."""
    try:
        for email in emails:
            error_msg = None
            resource = None
            user = _get_user_by_criteria(None, email)

            if resource_name:
                resource = Resource.query.filter_by(
                    name=resource_name).one_or_none()
            elif resource_type in ResourceType._member_names_:
                resources = Resource.query.filter_by(type_=resource_type).all()
                if resources and len(resources) > 1:
                    click.secho(
                        f"ERROR: There are more than one `{resource_type}` resource. "
                        "Please provide resource name with `--resource-name` option to specify the exact resource.",
                        fg="red",
                        err=True,
                    )
                    sys.exit(1)
                else:
                    resource = resources[0]

            if not user:
                error_msg = f"ERROR: Provided user {email} does not exist."
            elif not resource:
                resources = [
                    f"{resource.type_.name} ({resource.name})"
                    for resource in Resource.query
                ]
                error_msg = (
                    f"ERROR: Provided resource `{resource_name or resource_type}` does not exist. "
                    if resource_name or resource_type else
                    "ERROR: Please provide a resource. ")
                error_msg += f"Available resources are: {', '.join(resources)}."
            if error_msg:
                click.secho(
                    error_msg,
                    fg="red",
                    err=True,
                )
                sys.exit(1)

            user_resource = UserResource.query.filter_by(
                user=user, resource=resource).one_or_none()
            if user_resource:
                user_resource.quota_limit = limit
                Session.add(user_resource)
            else:
                # Create user resource in case there isn't one. Useful for old users.
                user.resources.append(
                    UserResource(
                        user_id=user.id_,
                        resource_id=resource.id_,
                        quota_limit=limit,
                        quota_used=0,
                    ))
        Session.commit()
        click.secho(
            f"Quota limit {limit} for '{resource.type_.name} ({resource.name})' successfully set to users {emails}.",
            fg="green",
        )
    except Exception as e:
        logging.debug(traceback.format_exc())
        logging.debug(str(e))
        click.echo(
            click.style("Quota could not be set: \n{}".format(str(e)),
                        fg="red"),
            err=True,
        )