2014-10-01 17:55:09 +00:00
|
|
|
import string
|
2014-04-10 04:26:55 +00:00
|
|
|
import logging
|
|
|
|
import json
|
|
|
|
|
2014-10-01 17:55:09 +00:00
|
|
|
from random import SystemRandom
|
2014-04-10 04:26:55 +00:00
|
|
|
from app import app
|
|
|
|
from flask import request
|
|
|
|
|
|
|
|
from endpoints.api import (ApiResource, nickname, resource, validate_json_request, request_error,
|
|
|
|
log_action, internal_only, NotFound, require_user_admin, format_date,
|
|
|
|
InvalidToken, require_scope, format_date, hide_if, show_if, parse_args,
|
2014-10-01 17:55:09 +00:00
|
|
|
query_param, abort, require_fresh_login)
|
2014-04-10 04:26:55 +00:00
|
|
|
|
|
|
|
from endpoints.api.logs import get_logs
|
|
|
|
|
|
|
|
from data import model
|
|
|
|
from auth.permissions import SuperUserPermission
|
|
|
|
from auth.auth_context import get_authenticated_user
|
2014-10-01 17:55:09 +00:00
|
|
|
from util.useremails import send_confirmation_email, send_recovery_email
|
2014-04-10 04:26:55 +00:00
|
|
|
|
|
|
|
import features
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
@resource('/v1/superuser/logs')
|
|
|
|
@internal_only
|
|
|
|
@show_if(features.SUPER_USERS)
|
|
|
|
class SuperUserLogs(ApiResource):
|
|
|
|
""" Resource for fetching all logs in the system. """
|
|
|
|
@nickname('listAllLogs')
|
|
|
|
@parse_args
|
|
|
|
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
|
|
|
|
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
|
|
|
|
@query_param('performer', 'Username for which to filter logs.', type=str)
|
|
|
|
def get(self, args):
|
|
|
|
""" List the logs for the current system. """
|
|
|
|
if SuperUserPermission().can():
|
|
|
|
performer_name = args['performer']
|
|
|
|
start_time = args['starttime']
|
|
|
|
end_time = args['endtime']
|
|
|
|
|
|
|
|
return get_logs(start_time, end_time)
|
|
|
|
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
|
|
|
|
def user_view(user):
|
|
|
|
return {
|
|
|
|
'username': user.username,
|
|
|
|
'email': user.email,
|
|
|
|
'verified': user.verified,
|
|
|
|
'super_user': user.username in app.config['SUPER_USERS']
|
|
|
|
}
|
|
|
|
|
|
|
|
@resource('/v1/superuser/users/')
|
|
|
|
@internal_only
|
|
|
|
@show_if(features.SUPER_USERS)
|
|
|
|
class SuperUserList(ApiResource):
|
|
|
|
""" Resource for listing users in the system. """
|
2014-10-01 17:55:09 +00:00
|
|
|
schemas = {
|
|
|
|
'CreateInstallUser': {
|
|
|
|
'id': 'CreateInstallUser',
|
|
|
|
'description': 'Data for creating a user',
|
|
|
|
'required': ['username', 'email'],
|
|
|
|
'properties': {
|
|
|
|
'username': {
|
|
|
|
'type': 'string',
|
|
|
|
'description': 'The username of the user being created'
|
|
|
|
},
|
|
|
|
|
|
|
|
'email': {
|
|
|
|
'type': 'string',
|
|
|
|
'description': 'The email address of the user being created'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@require_fresh_login
|
2014-04-10 04:26:55 +00:00
|
|
|
@nickname('listAllUsers')
|
|
|
|
def get(self):
|
|
|
|
""" Returns a list of all users in the system. """
|
|
|
|
if SuperUserPermission().can():
|
|
|
|
users = model.get_active_users()
|
|
|
|
return {
|
|
|
|
'users': [user_view(user) for user in users]
|
|
|
|
}
|
|
|
|
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
|
2014-10-01 17:55:09 +00:00
|
|
|
@require_fresh_login
|
|
|
|
@nickname('createInstallUser')
|
|
|
|
@validate_json_request('CreateInstallUser')
|
|
|
|
def post(self):
|
|
|
|
""" Creates a new user. """
|
|
|
|
user_information = request.get_json()
|
|
|
|
if SuperUserPermission().can():
|
|
|
|
username = user_information['username']
|
|
|
|
email = user_information['email']
|
|
|
|
|
|
|
|
# Generate a temporary password for the user.
|
|
|
|
random = SystemRandom()
|
|
|
|
password = ''.join([random.choice(string.ascii_uppercase + string.digits) for _ in range(32)])
|
|
|
|
|
|
|
|
# Create the user.
|
|
|
|
user = model.create_user(username, password, email, auto_verify=not features.MAILING)
|
|
|
|
|
|
|
|
# If mailing is turned on, send the user a verification email.
|
|
|
|
if features.MAILING:
|
|
|
|
confirmation = model.create_confirm_email_code(user, new_email=user.email)
|
|
|
|
send_confirmation_email(user.username, user.email, confirmation.code)
|
|
|
|
|
|
|
|
return {
|
|
|
|
'username': username,
|
|
|
|
'email': email,
|
|
|
|
'password': password
|
|
|
|
}
|
|
|
|
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
|
|
|
|
@resource('/v1/superusers/users/<username>/sendrecovery')
|
|
|
|
@internal_only
|
|
|
|
@show_if(features.SUPER_USERS)
|
|
|
|
@show_if(features.MAILING)
|
|
|
|
class SuperUserSendRecoveryEmail(ApiResource):
|
|
|
|
""" Resource for sending a recovery user on behalf of a user. """
|
|
|
|
@require_fresh_login
|
|
|
|
@nickname('sendInstallUserRecoveryEmail')
|
|
|
|
def post(self, username):
|
|
|
|
if SuperUserPermission().can():
|
|
|
|
user = model.get_user(username)
|
|
|
|
if not user or user.organization or user.robot:
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
if username in app.config['SUPER_USERS']:
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
code = model.create_reset_password_email_code(user.email)
|
|
|
|
send_recovery_email(user.email, code.code)
|
|
|
|
return {
|
|
|
|
'email': user.email
|
|
|
|
}
|
|
|
|
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
|
2014-04-10 04:26:55 +00:00
|
|
|
@resource('/v1/superuser/users/<username>')
|
|
|
|
@internal_only
|
|
|
|
@show_if(features.SUPER_USERS)
|
|
|
|
class SuperUserManagement(ApiResource):
|
|
|
|
""" Resource for managing users in the system. """
|
|
|
|
schemas = {
|
|
|
|
'UpdateUser': {
|
|
|
|
'id': 'UpdateUser',
|
|
|
|
'type': 'object',
|
|
|
|
'description': 'Description of updates for a user',
|
|
|
|
'properties': {
|
|
|
|
'password': {
|
|
|
|
'type': 'string',
|
|
|
|
'description': 'The new password for the user',
|
|
|
|
},
|
|
|
|
'email': {
|
|
|
|
'type': 'string',
|
|
|
|
'description': 'The new e-mail address for the user',
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2014-10-01 17:55:09 +00:00
|
|
|
@require_fresh_login
|
2014-04-10 04:26:55 +00:00
|
|
|
@nickname('getInstallUser')
|
|
|
|
def get(self, username):
|
|
|
|
""" Returns information about the specified user. """
|
|
|
|
if SuperUserPermission().can():
|
2014-10-01 17:55:09 +00:00
|
|
|
user = model.get_user(username)
|
|
|
|
if not user or user.organization or user.robot:
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
return user_view(user)
|
2014-04-10 04:26:55 +00:00
|
|
|
|
|
|
|
abort(403)
|
|
|
|
|
2014-10-01 17:55:09 +00:00
|
|
|
@require_fresh_login
|
2014-04-10 04:26:55 +00:00
|
|
|
@nickname('deleteInstallUser')
|
|
|
|
def delete(self, username):
|
|
|
|
""" Deletes the specified user. """
|
|
|
|
if SuperUserPermission().can():
|
|
|
|
user = model.get_user(username)
|
|
|
|
if not user or user.organization or user.robot:
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
if username in app.config['SUPER_USERS']:
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
model.delete_user(user)
|
|
|
|
return 'Deleted', 204
|
|
|
|
|
|
|
|
abort(403)
|
|
|
|
|
2014-10-01 17:55:09 +00:00
|
|
|
@require_fresh_login
|
2014-04-10 04:26:55 +00:00
|
|
|
@nickname('changeInstallUser')
|
|
|
|
@validate_json_request('UpdateUser')
|
|
|
|
def put(self, username):
|
|
|
|
""" Updates information about the specified user. """
|
|
|
|
if SuperUserPermission().can():
|
|
|
|
user = model.get_user(username)
|
|
|
|
if not user or user.organization or user.robot:
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
if username in app.config['SUPER_USERS']:
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
user_data = request.get_json()
|
|
|
|
if 'password' in user_data:
|
|
|
|
model.change_password(user, user_data['password'])
|
|
|
|
|
|
|
|
if 'email' in user_data:
|
|
|
|
model.update_email(user, user_data['email'])
|
|
|
|
|
|
|
|
return user_view(user)
|
|
|
|
|
|
|
|
abort(403)
|