Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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,
    )
Exemple #4
0
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,
    )
Exemple #5
0
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',
        },
    )
Exemple #6
0
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',
        },
    )
Exemple #7
0
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))
Exemple #8
0
 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
Exemple #9
0
 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
Exemple #10
0
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...')
Exemple #11
0
 def test_encrypt_decrypt_password(self, password, mock_rsa_key):
     assert decrypt_password(
         encrypt_password(password, mock_rsa_key),
         mock_rsa_key,
     ) == password
Exemple #12
0
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',
        },
    )
Exemple #13
0
 def test_encrypt_decrypt_password(self, password, mock_rsa_key):
     assert decrypt_password(
         encrypt_password(password, mock_rsa_key),
         mock_rsa_key,
     ) == password