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 = IndivoClient(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, settings.INDIVO_SERVER_LOCATION)
        ret = api.check_account_secrets(account_id=account_id, primary_secret=primary_secret, parameters={
            'secondary_secret': secondary_secret
        })
        
        # secrets are valid, set the new password:
        if 200 == ret.response.get('response_status', 0):
            params['SECONDARY_SECRET'] = secondary_secret
            
            # get account info
            ret = api.account_info(account_id = account_id)
            account = utils.parse_account_xml(ret.response.get('response_data') 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:
                    ret = api.account_set_password(account_id=account_id, data={'password': pw1})
                    
                    # password was reset, log the user in
                    if 200 == ret.response.get('response_status', 0):
                        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(ret.response.get('response_data') 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(ret.response.get('response_data') or 'Wrong confirmation code')
    
    return utils.render_template('ui/reset_password', params)
def index(request):
  if tokens_p(request):
    # get the realname here. we already have it in the js account model
    api = IndivoClient(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, settings.INDIVO_SERVER_LOCATION)
    account_id = urllib.unquote(request.session['oauth_token_set']['account_id'])
    ret = api.account_info(account_id = account_id)
    e = ET.fromstring(ret.response['response_data'])
    fullname = e.findtext('fullName')
    return utils.render_template('ui/index',
      { 'ACCOUNT_ID': account_id,
        'FULLNAME': fullname,
        'HIDE_GET_MORE_APPS': settings.HIDE_GET_MORE_APPS,
        'HIDE_SHARING': settings.HIDE_SHARING })
  else:
    return HttpResponseRedirect(reverse(login))
def forgot_password_3(request):
  errors = {'generic': 'There was a problem resetting your password. Please try again. If you are unable to set up your account please contact support.'}
  account_id = request.POST['account_id']
  password = request.POST['pw1']
  api = IndivoClient(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, settings.INDIVO_SERVER_LOCATION)
  ret = api.account_info(account_id = account_id)
  e = ET.fromstring(ret.response['response_data'])
  username = e.find('authSystem').get('username')
  ret = api.account_set_password(account_id = account_id, data={'password':password})
  
  if ret.response['response_status'] == 200:
    tokens_get_from_server(request, username, password)
    return HttpResponseRedirect(reverse(index))
  else:
    return utils.render_template('ui/forgot_password_3', {'ERROR': errors['generic']})
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 = IndivoClient(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, settings.INDIVO_SERVER_LOCATION)
            ret = api.account_secret_resend(account_id=account_id)
            
            if 404 == ret.response.get('response_status', 0):
                params['ERROR'] = ErrorStr('Unknown account')
            elif 200 != ret.response.get('response_status', 0):
                params['ERROR'] = ErrorStr(ret.response.get('response_data', 'Server Error'))
            
            # re-sent the primary, display a secondary if there is one
            else:
                params['MESSAGE'] = _('The activation email has been sent')
                
                ret = api.account_info(account_id=account_id)
                status = ret.response.get('response_status', 500)
                if 404 == status:
                    params['ERROR'] = ErrorStr('Unknown account')
                elif 200 != status:
                    params['ERROR'] = ErrorStr(ret.response.get('response_data', 'Server Error'))
                else:
                    account_xml = ret.response.get('response_data', '<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_setup(request, account_id, primary_secret, secondary_secret):
    """
    http://localhost/accounts/[email protected]/setup/taOFzInlYlDKLbiM
    """
    api = IndivoClient(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, settings.INDIVO_SERVER_LOCATION)
    
    # 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)
    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
        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)
        
        # verify SECONDARY secret as well, if there is one
        if has_secondary_secret:
            ret = api.check_account_secrets(account_id=account_id, primary_secret=primary_secret, parameters={'secondary_secret': secondary_secret})
            if 200 != ret.response.get('response_status', 0):
                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
        ret = api.add_auth_system(
            account_id = account_id,
            data = {
                  'system': 'password',
                'username': username,
                'password': password
            })
        
        if 200 == ret.response['response_status']:
            # everything's OK, log this person in, hard redirect to change location
            try:
                tokens_get_from_server(request, username, password)
            except IOError as e:
                return utils.render_template(LOGIN_PAGE, {'ERROR': ErrorStr(e.strerror), 'RETURN_URL': request.POST.get('return_url', '/'), 'SETTINGS': settings})
            return HttpResponseRedirect('/')
        elif 400 == ret.response['response_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 = 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)