def make_account_request(account, password): request = NewAccountRequest( user_name=account['user_name'], real_name=account['group_name'], is_group=True, calnet_uid=None, callink_oid=account['callink_oid'], email=account['email'], encrypted_password=encrypt_password( password, RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) print() print(bold('Pending account request:')) print( dedent("""\ User Name: {request.user_name} Group Name: {request.real_name} CalLink OID: {request.callink_oid} Email: {request.email} """).format(request=request)) return request
def make_account_request(account, password): request = NewAccountRequest( user_name=account['user_name'], real_name=account['group_name'], is_group=True, calnet_uid=None, callink_oid=account['callink_oid'], email=account['email'], encrypted_password=encrypt_password( password, RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) print() print(bold('Pending account request:')) print(dedent( """\ User Name: {request.user_name} Group Name: {request.real_name} CalLink OID: {request.callink_oid} Email: {request.email} """ ).format(request=request)) return request
def fake_new_account_request(mock_rsa_key): yield NewAccountRequest( user_name='someuser', real_name='Some User', is_group=False, calnet_uid=123456, callink_oid=None, email='*****@*****.**', encrypted_password=encrypt_password('hunter2000', RSA.importKey(WEAK_KEY)), handle_warnings=NewAccountRequest.WARNINGS_WARN, )
def request_account( request: HttpRequest) -> Union[HttpResponseRedirect, HttpResponse]: calnet_uid = request.session['calnet_uid'] status = 'new_request' existing_accounts = search.users_by_calnet_uid(calnet_uid) groups_for_user = groups_by_student_signat(calnet_uid) eligible_new_group_accounts, existing_group_accounts = {}, {} for group_oid in groups_for_user: if not group_by_oid(group_oid)['accounts'] or group_oid in [ group[0] for group in TEST_GROUP_ACCOUNTS ]: eligible_new_group_accounts[group_oid] = groups_for_user[group_oid] else: existing_group_accounts[group_oid] = groups_for_user[group_oid] if existing_accounts and not eligible_new_group_accounts and calnet_uid not in TESTER_CALNET_UIDS: return render( request, 'account/register/already-has-account.html', { 'account': ', '.join(existing_accounts), 'calnet_uid': calnet_uid, 'title': 'You already have an account', }, ) # ensure we can even find them in university LDAP # (alumni etc. might not be readable in LDAP but can still auth via CalNet) if not user_attrs_ucb(calnet_uid): return render( request, 'account/register/cant-find-in-ldap.html', { 'calnet_uid': calnet_uid, 'title': 'Unable to read account information', }, ) real_name = directory.name_by_calnet_uid(calnet_uid) association_choices = [] if not existing_accounts or calnet_uid in TESTER_CALNET_UIDS: association_choices.append((calnet_uid, real_name)) for group_oid, group in eligible_new_group_accounts.items(): association_choices.append((group_oid, group['name'])) if request.method == 'POST': form = ApproveForm(request.POST, association_choices=association_choices) if form.is_valid(): assoc_id = int(form.cleaned_data['account_association']) is_group_account = assoc_id != calnet_uid if is_group_account: req = NewAccountRequest( user_name=form.cleaned_data['ocf_login_name'], real_name=eligible_new_group_accounts[assoc_id]['name'], is_group=True, calnet_uid=None, callink_oid=assoc_id, email=form.cleaned_data['contact_email'], encrypted_password=encrypt_password( form.cleaned_data['password'], RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) else: req = NewAccountRequest( user_name=form.cleaned_data['ocf_login_name'], real_name=real_name, is_group=False, calnet_uid=calnet_uid, callink_oid=None, email=form.cleaned_data['contact_email'], encrypted_password=encrypt_password( form.cleaned_data['password'], RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) if 'warnings-submit' in request.POST: req = req._replace( handle_warnings=NewAccountRequest.WARNINGS_SUBMIT, ) task = validate_then_create_account.delay(req) task.wait(timeout=5) if isinstance(task.result, NewAccountResponse): if task.result.status == NewAccountResponse.REJECTED: status = 'has_errors' form.add_error(None, task.result.errors) elif task.result.status == NewAccountResponse.FLAGGED: status = 'has_warnings' form.add_error(None, task.result.errors) elif task.result.status == NewAccountResponse.PENDING: return HttpResponseRedirect(reverse('account_pending')) else: raise AssertionError('Unexpected state reached') else: # validation was successful, the account is being created now request.session['approve_task_id'] = task.result return HttpResponseRedirect(reverse('wait_for_account')) else: form = ApproveForm(association_choices=association_choices) return render( request, 'account/register/index.html', { 'calnet_uid': calnet_uid, 'existing_accounts': existing_accounts, 'existing_group_accounts': existing_group_accounts, 'form': form, 'real_name': real_name, 'status': status, 'title': 'Request an OCF account', }, )
def request_account(request): calnet_uid = request.session['calnet_uid'] status = 'new_request' existing_accounts = search.users_by_calnet_uid(calnet_uid) if existing_accounts and calnet_uid not in TESTER_CALNET_UIDS: return render( request, 'account/register/already-has-account.html', { 'account': ', '.join(existing_accounts), 'calnet_uid': calnet_uid, 'title': 'You already have an account', }, ) # ensure we can even find them in university LDAP # (alumni etc. might not be readable in LDAP but can still auth via CalNet) if not user_attrs_ucb(calnet_uid): return render( request, 'account/register/cant-find-in-ldap.html', { 'calnet_uid': calnet_uid, 'title': 'Unable to read account information', }, ) real_name = directory.name_by_calnet_uid(calnet_uid) if request.method == 'POST': form = ApproveForm(request.POST) if form.is_valid(): req = NewAccountRequest( user_name=form.cleaned_data['ocf_login_name'], real_name=real_name, is_group=False, calnet_uid=calnet_uid, callink_oid=None, email=form.cleaned_data['contact_email'], encrypted_password=encrypt_password( form.cleaned_data['password'], RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) if 'warnings-submit' in request.POST: req = req._replace( handle_warnings=NewAccountRequest.WARNINGS_SUBMIT, ) task = validate_then_create_account.delay(req) task.wait(timeout=5) if isinstance(task.result, NewAccountResponse): if task.result.status == NewAccountResponse.REJECTED: status = 'has_errors' form._errors[NON_FIELD_ERRORS] = form.error_class( task.result.errors) elif task.result.status == NewAccountResponse.FLAGGED: status = 'has_warnings' form._errors[NON_FIELD_ERRORS] = form.error_class( task.result.errors) elif task.result.status == NewAccountResponse.PENDING: return HttpResponseRedirect(reverse('account_pending')) else: raise AssertionError('Unexpected state reached') else: # validation was successful, the account is being created now request.session['approve_task_id'] = task.result return HttpResponseRedirect(reverse('wait_for_account')) else: form = ApproveForm() return render( request, 'account/register/index.html', { 'form': form, 'real_name': real_name, 'status': status, 'title': 'Request an OCF account', }, )
def request_account(request): calnet_uid = request.session['calnet_uid'] status = 'new_request' existing_accounts = search.users_by_calnet_uid(calnet_uid) real_name = directory.name_by_calnet_uid(calnet_uid) if calnet_uid not in settings.TESTER_CALNET_UIDS and existing_accounts: return render_to_response('request-account/already-has-account.html', { 'calnet_uid': calnet_uid, 'calnet_url': settings.LOGOUT_URL }) if request.method == 'POST': form = ApproveForm(request.POST) if form.is_valid(): req = NewAccountRequest( user_name=form.cleaned_data['ocf_login_name'], real_name=real_name, is_group=False, calnet_uid=calnet_uid, callink_oid=None, email=form.cleaned_data['contact_email'], encrypted_password=encrypt_password( form.cleaned_data['password'], settings.PASSWORD_ENCRYPTION_PUBKEY, ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) if 'warnings-submit' in request.POST: req = req._replace( handle_warnings=NewAccountRequest.WARNINGS_SUBMIT, ) task = validate_then_create_account.delay(req) task.wait(timeout=5) if isinstance(task.result, NewAccountResponse): if task.result.status == NewAccountResponse.REJECTED: status = 'has_errors' form._errors[NON_FIELD_ERRORS] = form.error_class(task.result.errors) elif task.result.status == NewAccountResponse.FLAGGED: status = 'has_warnings' form._errors[NON_FIELD_ERRORS] = form.error_class(task.result.errors) elif task.result.status == NewAccountResponse.PENDING: return HttpResponseRedirect(reverse('account_pending')) else: raise AssertionError('Unexpected state reached') else: # validation was successful, the account is being created now request.session['approve_task_id'] = task.result return HttpResponseRedirect(reverse('wait_for_account')) else: form = ApproveForm() return render_to_response('request-account/form.html', { 'form': form, 'real_name': real_name, 'status': status, }, context_instance=RequestContext(request))
def test_encrypt_decrypt_password(self, password, mock_rsa_key): assert decrypt_password( encrypt_password(password, RSA.importKey(WEAK_KEY)), RSA.importKey(WEAK_KEY), ) == password
def main(): def_group_name = '' def_callink_oid = '' def_email = '' parser = ArgumentParser(description='Create new OCF group accounts.') parser.add_argument('oid', type=int, nargs='?', help='CalLink OID for the group.') args = parser.parse_args() if args.oid: group = group_by_oid(args.oid) if not group: print(red('No group with OID {}').format(args.oid)) return if group['accounts']: print(yellow( 'Warning: there is an existing group account with OID {}: {}'.format( args.oid, ', '.join(group['accounts']), ), )) input('Press any key to continue...') def_group_name = group['name'] def_callink_oid = args.oid def_email = group['email'] content = TEMPLATE.format( group_name=def_group_name, callink_oid=def_callink_oid, email=def_email ) while True: content = edit_file(content) try: account = yaml.safe_load(content) except yaml.YAMLError as ex: print('Error parsing your YAML:') print(ex) input('Press enter to continue...') continue missing_key = False for key in ['user_name', 'group_name', 'callink_oid', 'email']: if account.get(key) is None: print('Missing value for key: ' + key) missing_key = True if missing_key: input('Press enter to continue...') continue try: password = prompt_for_new_password( validator=lambda pwd: validate_password( account['user_name'], pwd), ) except KeyboardInterrupt: # we want to allow cancelling during the "enter password" stage # without completely exiting approve print() input('Press enter to start over (or ^C again to cancel)...') continue request = NewAccountRequest( user_name=account['user_name'], real_name=account['group_name'], is_group=True, calnet_uid=None, callink_oid=account['callink_oid'], email=account['email'], encrypted_password=encrypt_password( password, RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) print() print(bold('Pending account request:')) print(dedent( """\ User Name: {request.user_name} Group Name: {request.real_name} CalLink OID: {request.callink_oid} Email: {request.email} """ ).format(request=request)) if input('Submit request? [yN] ') != 'y': input('Press enter to continue.') continue conf = ConfigParser() conf.read('/etc/ocf-create/ocf-create.conf') celery = Celery( broker=conf.get('celery', 'broker'), backend=conf.get('celery', 'backend'), ) tasks = get_tasks(celery) task = tasks.validate_then_create_account.delay(request) response = wait_for_task(celery, task) new_request = None if response.status == NewAccountResponse.REJECTED: print(bold(red( 'Account requested was rejected for the following reasons:' ))) for error in response.errors: print(red(' - {}'.format(error))) input('Press enter to start over (or ^C to cancel)...') continue elif response.status == NewAccountResponse.FLAGGED: print(bold(yellow( 'Account requested was flagged for the following reasons:' ))) for error in response.errors: print(yellow(' - {}'.format(error))) print(bold( 'You can either create the account anyway, or go back and ' 'modify the request.' )) choice = input('Create the account anyway? [yN] ') if choice in ('y', 'Y'): new_request = request._replace( handle_warnings=NewAccountRequest.WARNINGS_CREATE, ) task = tasks.validate_then_create_account.delay(new_request) response = wait_for_task(celery, task) else: input('Starting over, press enter to continue...') continue if response.status == NewAccountResponse.CREATED: print(bold(green('Account created!'))) print('Your account was created successfully.') print('You\'ve been sent an email with more information.') return else: # this shouldn't be possible; we must have entered some weird state # TODO: report via ocflib print(bold(red('Error: Entered unexpected state.'))) print(red('The request we submitted was:')) print(red(request)) print(red('The new request we submitted (if any) was:')) print(red(new_request)) print(red('The response we received was:')) print(red(response)) print(bold(red('Not really sure what to do here, sorry.'))) input('Press enter to start over...')
def test_encrypt_decrypt_password(self, password, mock_rsa_key): assert decrypt_password( encrypt_password(password, mock_rsa_key), mock_rsa_key, ) == password
def request_account(request): calnet_uid = request.session['calnet_uid'] status = 'new_request' existing_accounts = search.users_by_calnet_uid(calnet_uid) if existing_accounts and calnet_uid not in TESTER_CALNET_UIDS: return render( request, 'account/register/already-has-account.html', { 'account': ', '.join(existing_accounts), 'calnet_uid': calnet_uid, 'title': 'You already have an account', }, ) # ensure we can even find them in university LDAP # (alumni etc. might not be readable in LDAP but can still auth via CalNet) if not user_attrs_ucb(calnet_uid): return render( request, 'account/register/cant-find-in-ldap.html', { 'calnet_uid': calnet_uid, 'title': 'Unable to read account information', }, ) real_name = directory.name_by_calnet_uid(calnet_uid) if request.method == 'POST': form = ApproveForm(request.POST) if form.is_valid(): req = NewAccountRequest( user_name=form.cleaned_data['ocf_login_name'], real_name=real_name, is_group=False, calnet_uid=calnet_uid, callink_oid=None, email=form.cleaned_data['contact_email'], encrypted_password=encrypt_password( form.cleaned_data['password'], RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) if 'warnings-submit' in request.POST: req = req._replace( handle_warnings=NewAccountRequest.WARNINGS_SUBMIT, ) task = validate_then_create_account.delay(req) task.wait(timeout=5) if isinstance(task.result, NewAccountResponse): if task.result.status == NewAccountResponse.REJECTED: status = 'has_errors' form._errors[NON_FIELD_ERRORS] = form.error_class(task.result.errors) elif task.result.status == NewAccountResponse.FLAGGED: status = 'has_warnings' form._errors[NON_FIELD_ERRORS] = form.error_class(task.result.errors) elif task.result.status == NewAccountResponse.PENDING: return HttpResponseRedirect(reverse('account_pending')) else: raise AssertionError('Unexpected state reached') else: # validation was successful, the account is being created now request.session['approve_task_id'] = task.result return HttpResponseRedirect(reverse('wait_for_account')) else: form = ApproveForm() return render( request, 'account/register/index.html', { 'form': form, 'real_name': real_name, 'status': status, 'title': 'Request an OCF account', }, )