def register(request): """ http://localhost/change_password Returns the register template (GET) or creates a new account (POST) """ if HTTP_METHOD_POST == request.method: if not settings.REGISTRATION.get('enable', False): return utils.render_template('ui/error', {'error_message': ErrorStr('Registration disabled'), 'error_status': 403}) # create the account post = request.POST set_primary = settings.REGISTRATION.get('set_primary_secret', 1) user_hash = {'account_id': post.get('account_id'), 'contact_email': post.get('account_id'), # TODO:the contact_email key is not present in the register form for now, so use the account_id 'full_name': post.get('full_name'), 'primary_secret_p': set_primary, 'secondary_secret_p': settings.REGISTRATION.get('set_secondary_secret', 1)} api = get_api() res, content = api.account_create(body=user_hash) # on success, forward to page according to the secrets that were or were not generated if '200' == res['status']: account_xml = content or '<root/>' account = utils.parse_account_xml(account_xml) account_id = account.get('id') if not set_primary: return utils.render_template(LOGIN_PAGE, {'MESSAGE': _('You have successfully registered.') + ' ' + _('After an administrator has approved your account you may login.'), 'SETTINGS': settings}) # display the secondary secret if there is one has_secondary_secret = (None != account.get('secret') and len(account.get('secret')) > 0) if has_secondary_secret: return utils.render_template('ui/register', {'SETTINGS': settings, 'ACCOUNT_ID': account_id, 'SECONDARY': account.get('secret'), 'MESSAGE': _('You have successfully registered.') + ' ' + _('At the link sent to your email address, enter the following activation code:')}) return HttpResponseRedirect('/accounts/%s/send_secret/sent' % account_id) return utils.render_template('ui/register', {'ERROR': ErrorStr((content or 'Setup failed')), 'SETTINGS': settings}) return utils.render_template('ui/register', {'SETTINGS': settings})
def reset_password(request, account_id, primary_secret): """ http://localhost/accounts/[email protected]/reset_password/taOFzInlYlDKLbiM """ params = {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'SETTINGS': settings} if HTTP_METHOD_POST == request.method: secondary_secret = request.POST.get('conf1') + request.POST.get('conf2') # check the validity of the primary and secondary secrets api = get_api() resp, content = api.account_check_secrets(account_email=account_id, primary_secret=primary_secret, body={ 'secondary_secret': secondary_secret }) # secrets are valid, set the new password: if '200' == resp['status']: params['SECONDARY_SECRET'] = secondary_secret # get account info resp, content = api.account_info(account_email = account_id) account = utils.parse_account_xml(content or '<root/>') # check passwords pw1 = request.POST.get('pw1') if len(pw1) >= (settings.REGISTRATION['min_password_length'] or 8): pw2 = request.POST.get('pw2') if pw1 == pw2: resp, content = api.account_password_set(account_email=account_id, body={'password': pw1}) # password was reset, log the user in if '200' == resp['status']: try: try: username = account['auth_systems'][0]['username'] # TODO: I don't like this... tokens_get_from_server(request, username, pw1) except Exception as e: params['ERROR'] = ErrorStr(str(e)) # We'll never see this return HttpResponseRedirect(reverse(index)) except IOError as e: params['ERROR'] = ErrorStr(e.strerror) else: params['ERROR'] = ErrorStr(content or 'Password reset failed') else: params['ERROR'] = ErrorStr('Passwords do not match') else: params['ERROR'] = ErrorStr('Password too short') # wrong secrets (primary or secondary) else: params['ERROR'] = ErrorStr(content or 'Wrong confirmation code') return utils.render_template('ui/reset_password', params)
def send_secret(request, account_id, status): """ http://localhost/accounts/[[email protected]/]send_secret/[(sent|wrong)] """ params = {'ACCOUNT_ID': account_id} if HTTP_METHOD_GET == request.method: if account_id: if 'wrong' == status: params['ERROR'] = ErrorStr('Wrong secret') elif 'sent' == status: params['MESSAGE'] = _('Use the link sent to your email address to proceed with account activation') elif HTTP_METHOD_POST == request.method: account_id = request.POST.get('account_id', '') params['ACCOUNT_ID'] = account_id # re-send the primary secret and display the secondary, if needed if request.POST.get('re_send', False): api = get_api() resp, content = api.account_resend_secret(account_email=account_id) if '404' == resp['status']: params['ERROR'] = ErrorStr('Unknown account') elif '200' != resp['status']: params['ERROR'] = ErrorStr(content or 'Error') # re-sent the primary, display a secondary if there is one else: params['MESSAGE'] = _('The activation email has been sent') resp, content = api.account_info(account_email=account_id) status = resp['status'] if '404' == status: params['ERROR'] = ErrorStr('Unknown account') elif '200' != status: params['ERROR'] = ErrorStr(resp.response.get('response_data', 'Server Error')) else: account_xml = content or '<root/>' account = utils.parse_account_xml(account_xml) has_secondary_secret = (None != account.get('secret') and len(account.get('secret')) > 0) if has_secondary_secret: params['MESSAGE'] += '. ' + ('At the link sent to your email address, enter the following activation code:') params['SECONDARY'] = account.get('secret') else: params['MESSAGE'] = _('Use the link sent to your email address to proceed with account activation') return utils.render_template('ui/send_secret', params)
def account_name(request, account_id): """ http://localhost/accounts/[email protected]/name """ api = get_api() resp, content = api.account_info(account_email=account_id) status = resp['status'] dict = {'account_id': account_id} if '404' == status: dict['error'] = ErrorStr('Unknown account').str() elif '200' != status: dict['error'] = ErrorStr(ret.response.get('response_data', 'Server Error')).str() else: account = utils.parse_account_xml(content) dict['name'] = account.get('fullName') return HttpResponse(simplejson.dumps(dict))
def account_name(request, account_id): """ http://localhost/accounts/[email protected]/name """ api = get_api() ret = api.account_info(account_id=account_id) status = ret.response.get('response_status', 500) dict = {'account_id': account_id} if 404 == status: dict['error'] = ErrorStr('Unknown account').str() elif 200 != status: dict['error'] = ErrorStr(ret.response.get('response_data', 'Server Error')).str() else: account_xml = ret.response.get('response_data', '<root/>') account = utils.parse_account_xml(account_xml) dict['name'] = account.get('fullName') return HttpResponse(simplejson.dumps(dict))
def account_setup(request, account_id, primary_secret, secondary_secret): """ http://localhost/accounts/[email protected]/setup/taOFzInlYlDKLbiM """ api = get_api() # is this account already initialized? resp, content = api.account_info(account_email=account_id) status = resp['status'] if '404' == status: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('Unknown account')}) if '200' != status: return utils.render_template('ui/error', {'error_status': status, 'error_message': ErrorStr(content or 'Server Error')}) account_xml = content or '<root/>' account = utils.parse_account_xml(account_xml) account_state = account.get('state') has_primary_secret = (len(primary_secret) > 0) # TODO: Get this information from the server (API missing as of now) has_secondary_secret = (None != account.get('secret') and len(account.get('secret')) > 0) # if the account is already active, show login IF at least one auth-system is attached if 'active' == account_state: if len(account['auth_systems']) > 0: return utils.render_template(LOGIN_PAGE, {'MESSAGE': _('Your account is now active, you may log in below'), 'SETTINGS': settings}) elif 'uninitialized' != account_state: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('This account is %s' % account_state), 'SETTINGS': settings}) # received POST data, try to setup params = {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'SECONDARY_SECRET': secondary_secret, 'SETTINGS': settings} if HTTP_METHOD_POST == request.method: post = request.POST username = post.get('username', '').lower().strip() password = post.get('pw1') secondary_secret = post.get('secondary_secret', '') # verify PRIMARY secret first and send back to "resend secret" page if it is wrong resp, content = api.account_check_secrets(account_email=account_id, primary_secret=primary_secret) if '200' != resp['status']: return HttpResponseRedirect('/accounts/%s/send_secret/wrong' % account_id) # verify SECONDARY secret as well, if there is one if has_secondary_secret: resp, content = api.account_check_secrets(account_email=account_id, primary_secret=primary_secret, body={'secondary_secret': secondary_secret}) if '200' != resp['status']: params['ERROR'] = ErrorStr('Wrong confirmation code') return utils.render_template('ui/account_init', params) # verify passwords error = None if len(username) < 1: error = ErrorStr("Username too short") if len(password) < (settings.REGISTRATION['min_password_length'] or 8): error = ErrorStr("Password too short") elif password != post.get('pw2'): error = ErrorStr("Passwords do not match") if error is not None: params['ERROR'] = error return utils.render_template('ui/account_setup', params) # secrets are ok, passwords check out: Attach the login credentials to the account resp, content = api.account_authsystem_add( account_email = account_id, body = { 'system': 'password', 'username': username, 'password': password }) if '200' == resp['status']: # everything's OK, log this person in, hard redirect to change location resp, content = tokens_get_from_server(request, username, password) if resp['status'] != '200': return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr(e.strerror), 'RETURN_URL': request.POST.get('return_url', '/'), 'SETTINGS': settings}) return HttpResponseRedirect('/') elif '400' == resp['status']: params['ERROR'] = ErrorStr('Username already taken') return utils.render_template('ui/account_setup', params) params['ERROR'] = ErrorStr('account_init_error') return utils.render_template('ui/account_setup', params) # got no secondary_secret, go back to init step which will show a prompt for the secondary secret if has_secondary_secret and not secondary_secret: return HttpResponseRedirect('/accounts/%s/init/%s' % (account_id, primary_secret)) return utils.render_template('ui/account_setup', params)
def account_init(request, account_id, primary_secret): """ http://localhost/accounts/[email protected]/init/icmloNHxQrnCQKNn Legacy: http://localhost/indivoapi/accounts/[email protected]/initialize/icmloNHxQrnCQKNn """ api = get_api() try_to_init = False move_to_setup = False # is this account already initialized? resp, content = api.account_info(account_email=account_id) status = resp['status'] if '404' == status: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('Unknown account')}) if '200' != status: return utils.render_template('ui/error', {'error_status': status, 'error_message': ErrorStr(content or 'Server Error')}) account_xml = content or '<root/>' account = utils.parse_account_xml(account_xml) account_state = account.get('state') has_primary_secret = (len(primary_secret) > 0) # TODO: Get this information from the server (API missing as of now) secondary_secret = '' has_secondary_secret = (None != account.get('secret') and len(account.get('secret')) > 0) # if the account is already active, show login IF at least one auth-system is attached if 'uninitialized' != account_state: if 'active' == account_state: if len(account['auth_systems']) > 0: return utils.render_template(LOGIN_PAGE, {'MESSAGE': _('Your account is now active, you may log in below'), 'SETTINGS': settings}) else: move_to_setup = True else: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('This account is %s' % account_state), 'SETTINGS': settings}) # bail out if the primary secret is wrong if has_primary_secret: resp, content = api.account_check_secrets(account_email=account_id, primary_secret=primary_secret) if '200' != resp['status']: return HttpResponseRedirect('/accounts/%s/send_secret/wrong' % account_id) # GET the form; if we don't need a secondary secret, continue to the 2nd step automatically if HTTP_METHOD_GET == request.method: if not has_secondary_secret: try_to_init = True # POSTed the secondary secret if HTTP_METHOD_POST == request.method: secondary_secret = request.POST.get('conf1') + request.POST.get('conf2') try_to_init = True # try to initialize if try_to_init and not move_to_setup: data = {} if has_secondary_secret: data = {'secondary_secret': secondary_secret} resp, content = api.account_initialize(account_email = account_id, primary_secret = primary_secret, body = data) status = resp['status'] # on success also create the first record if we have a full_name and is enabled in settings if '200' == status: if settings.REGISTRATION['autocreate_record'] and account['fullName'] and len(account['fullName']) > 0: full_name = account['fullName'] email = account['contactEmail'] try: split_index = full_name.index(' ') given_name = full_name[0:split_index] family_name = full_name[split_index:] except ValueError: given_name = full_name family_name = full_name demographics = '''<Demographics xmlns="http://indivo.org/vocab/xml/documents#"> <dateOfBirth>1939-11-15</dateOfBirth> <gender>female</gender> <email>%s</email> <Name> <familyName>%s</familyName> <givenName>%s</givenName> </Name> </Demographics>''' % (email, family_name, given_name) res = _record_create(account_id, demographics) if 200 != res.status_code: utils.log("account_init(): Error creating a record after initializing the account, failing silently. The error was: %s" % res.content) move_to_setup = True elif '404' == status: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('Unknown account')}) elif '403' == status: return utils.render_template('ui/account_init', {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'ERROR': ErrorStr('Wrong confirmation code')}) else: utils.log("account_init(): Error initializing an account: %s" % content) return utils.render_template('ui/account_init', {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'ERROR': ErrorStr('Setup failed')}) # proceed to setup if we have the correct secondary secret params = {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'SETTINGS': settings} if move_to_setup and (not has_secondary_secret or len(secondary_secret) > 0): resp, content = api.account_check_secrets(account_email=account_id, primary_secret=primary_secret, body={'secondary_secret': secondary_secret}) status = resp['status'] if '200' == status: return HttpResponseRedirect('/accounts/%s/setup/%s/%s' % (account_id, primary_secret, secondary_secret)) if '403' == status: params['ERROR'] = ErrorStr('Wrong confirmation code') else: params['ERROR'] = content or 'Server Error' return utils.render_template('ui/account_init', params)
def account_init(request, account_id, primary_secret): """ http://localhost/accounts/[email protected]/init/icmloNHxQrnCQKNn Legacy: http://localhost/indivoapi/accounts/[email protected]/initialize/icmloNHxQrnCQKNn """ api = IndivoClient(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, settings.INDIVO_SERVER_LOCATION) try_to_init = False move_to_setup = False # is this account already initialized? ret = api.account_info(account_id=account_id) status = ret.response.get('response_status', 500) if 404 == status: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('Unknown account')}) if 200 != status: return utils.render_template('ui/error', {'error_status': status, 'error_message': ErrorStr(ret.response.get('response_data', 'Server Error'))}) account_xml = ret.response.get('response_data', '<root/>') account = utils.parse_account_xml(account_xml) account_state = account.get('state') has_primary_secret = (len(primary_secret) > 0) # TODO: Get this information from the server (API missing as of now) secondary_secret = '' has_secondary_secret = (None != account.get('secret') and len(account.get('secret')) > 0) # if the account is already active, show login IF at least one auth-system is attached if 'uninitialized' != account_state: if 'active' == account_state: if len(account['auth_systems']) > 0: return utils.render_template(LOGIN_PAGE, {'MESSAGE': _('Your account is now active, you may log in below'), 'SETTINGS': settings}) else: move_to_setup = True else: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('This account is %s' % account_state), 'SETTINGS': settings}) # bail out if the primary secret is wrong if has_primary_secret: ret = api.check_account_secrets(account_id=account_id, primary_secret=primary_secret) if 200 != ret.response.get('response_status', 0): return HttpResponseRedirect('/accounts/%s/send_secret/wrong' % account_id) # GET the form; if we don't need a secondary secret, continue to the 2nd step automatically if HTTP_METHOD_GET == request.method: if not has_secondary_secret: try_to_init = True # POSTed the secondary secret if HTTP_METHOD_POST == request.method: secondary_secret = request.POST.get('conf1') + request.POST.get('conf2') try_to_init = True # try to initialize if try_to_init and not move_to_setup: data = {} if has_secondary_secret: data = {'secondary_secret': secondary_secret} ret = api.account_initialize(account_id = account_id, primary_secret = primary_secret, data = data) status = ret.response.get('response_status', 0) # on success also create the first record if we have a full_name and is enabled in settings if 200 == status: if settings.REGISTRATION['autocreate_record'] and account['fullName'] and len(account['fullName']) > 0: res = _record_create(account_id, {'fullName': account['fullName'], 'email': account_id}) if 200 != res.status_code: utils.log("account_init(): Error creating a record after initializing the account, failing silently. The error was: %s" % res.content) move_to_setup = True elif 404 == status: return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr('Unknown account')}) elif 403 == status: return utils.render_template('ui/account_init', {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'ERROR': ErrorStr('Wrong confirmation code')}) else: utils.log("account_init(): Error initializing an account: %s" % ret.response) return utils.render_template('ui/account_init', {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'ERROR': ErrorStr('Setup failed')}) # proceed to setup if we have the correct secondary secret params = {'ACCOUNT_ID': account_id, 'PRIMARY_SECRET': primary_secret, 'SETTINGS': settings} if move_to_setup and (not has_secondary_secret or len(secondary_secret) > 0): ret = api.check_account_secrets(account_id=account_id, primary_secret=primary_secret, parameters={'secondary_secret': secondary_secret}) status = ret.response.get('response_status', 0) if 200 == status: return HttpResponseRedirect('/accounts/%s/setup/%s/%s' % (account_id, primary_secret, secondary_secret)) if 403 == status: params['ERROR'] = ErrorStr('Wrong confirmation code') else: params['ERROR'] = ret.response.get('response_data', 'Server Error') return utils.render_template('ui/account_init', params)