Exemplo n.º 1
0
def test_user_org_link(test_models):
    assert User.get(id=43).admin_for.count() == 10
    assert User.get(id=1).admin_for.count() == 0
    assert User.get(id=42).admin_for.count() > 0
    assert User.get(id=2).organisations.count() > 0
    assert Organisation.get(id=1).admins.count() == 1
    assert Organisation.get(id=5).users.count() > 0
    assert Organisation.get(id=5).admins.count() > 0
Exemplo n.º 2
0
def test_user_org_link_user_constraint(test_models):
    org = Organisation.get(id=1)
    uo = UserOrg(user=999999, org=org)
    with pytest.raises(User.DoesNotExist):
        uo.save()
Exemplo n.º 3
0
def confirm_organisation(token):
    """Registration confirmations.

    TODO: expand the spect as soon as the reqirements get sorted out.
    """
    clientSecret_url = None
    email = confirm_token(token)
    user = current_user

    if not email:
        app.error("token '%s'", token)
        app.login_manager.unauthorized()
    if user.email != email:
        flash(
            "The invitation to on-board the organisation wasn't sent to your email address...",
            "danger")
        return redirect(url_for("login"))

    # TODO: support for mutliple orgs and admins
    # TODO: admin role asigning to an exiting user
    # TODO: support for org not participating in Tuakiri
    form = OrgConfirmationForm()

    # For now only GET method is implemented will need post method for organisation
    # to enter client secret and client key for orcid
    if request.method == 'POST':
        if not form.validate():
            flash('Please fill in all fields and try again!', "danger")
        else:
            organisation = Organisation.get(email=email)
            if (not (user is None) and (not (organisation is None))):
                # Update Organisation
                organisation.confirmed = True
                organisation.orcid_client_id = form.orgOricdClientId.data
                organisation.orcid_secret = form.orgOrcidClientSecret.data
                organisation.save()

                # Update Orcid User
                user.confirmed = True
                user.save()
                with app.app_context():
                    msg = Message("Welcome to OrcidhHub", recipients=[email])
                    msg.body = "Congratulations your emailid has been confirmed and " \
                               "organisation onboarded successfully."
                    mail.send(msg)
                    flash("Your Onboarding is Completed!!!", "success")
                return redirect(url_for("login"))

    elif request.method == 'GET':

        form.orgEmailid.data = email
        form.orgName.data = user.organisation.name

        flash(
            """If you currently don't know Client id and Client Secret,
        Please request those by clicking on link 'Take me to ORCiD to obtain Client iD and Client Secret'
        and come back to this same place once you have them within 15 days""",
            "warning")

        clientSecret_url = iri_to_uri(
            MEMBER_API_FORM_BASE_URL) + "?" + urlencode(
                dict(new_existing=NEW_CREDENTIALS,
                     note=NOTE_ORCID + " " + user.organisation.name,
                     contact_email=email,
                     contact_name=user.name,
                     org_name=user.organisation.name,
                     cred_type=CRED_TYPE_PREMIUM,
                     app_name=APP_NAME + " at " + user.organisation.name,
                     app_description=APP_DESCRIPTION + " at " +
                     user.organisation.name,
                     app_url=APP_URL,
                     redirect_uri_1=redirect_uri))

    return render_template('orgconfirmation.html',
                           clientSecret_url=clientSecret_url,
                           form=form)
Exemplo n.º 4
0
def shib_login():
    """Shibboleth authenitcation handler.

    The (Apache) location should requier authentication using Shibboleth, e.g.,

    <Location /Tuakiri>
        AuthType shibboleth
        ShibRequireSession On
        require valid-user
        ShibUseHeaders On
    </Location>


    Flow:
        * recieve redicected request from SSO with authentication data in HTTP headers
        * process headeers
        * if the organisation isn't on-boarded, reject further access and redirect to the main loging page;
        * if the user isn't registered add the user with data received from Shibboleth
        * if the request has returning destination (next), redirect the user to it;
        * else choose the next view based on the role of the user:
            ** for a researcher, affiliation;
            ** for super user, the on-boarding of an organisation;
            ** for organisation administrator or technical contact, the completion of the on-boarding.
    """
    _next = request.args.get('_next')
    token = request.headers.get("Auedupersonsharedtoken")
    last_name = request.headers['Sn']
    first_name = request.headers['Givenname']
    email = request.headers['Mail']
    session["shib_O"] = shib_org_name = request.headers['O']
    name = request.headers.get('Displayname')

    try:
        # TODO: need a separate field for org name comimg from Tuakiri
        org = Organisation.get(name=shib_org_name)
    except Organisation.DoesNotExist:
        org = None

    try:
        user = User.get(User.email == email)

        # Add Shibboleth meta data if they are missing
        if not user.edu_person_shared_token:
            user.edu_person_shared_token = token
        if not user.name or org is not None and user.name == org.name and name:
            user.name = name
        if not user.first_name and first_name:
            user.firts_name = first_name
        if not user.last_name and last_name:
            user.last_name = last_name
        if not user.confirmed:
            user.confirmed = True
        # TODO: keep login auditing (last_loggedin_at... etc)

    except User.DoesNotExist:
        user = User.create(email=email,
                           name=name,
                           first_name=first_name,
                           last_name=last_name,
                           confirmed=True,
                           roles=Role.RESEARCHER,
                           edu_person_shared_token=token)

    if org is not None and org not in user.organisations:
        UserOrg.create(user=user, org=org)

        # TODO: need to find out a simple way of tracking
        # the organization user is logged in from:
    if org != user.organisation:
        user.organisation = org

    user.save()

    login_user(user)

    if _next:
        return redirect(_next)
    elif user.is_superuser:
        return redirect(url_for("invite_organisation"))
    elif org and org.confirmed:
        return redirect(url_for("link"))
    else:
        flash("Your organisation (%s) is not onboarded" % shib_org_name,
              "danger")

    return redirect(url_for("login"))
Exemplo n.º 5
0
def invite_organisation():
    """Invite an organisation to register.

    Flow:
        * Hub administrort (super user) invokes the page,
        * Fills in the form with the organisation and organisation technica contatct data (including an email address);
        * Submits the form;
        * A secure registration token gets ceated;
        * An email message with confirmation link gets created and sent off to the technical contact.
    """
    form = OrgRegistrationForm()
    if request.method == "POST":
        if not form.validate():
            flash("Please fill in all fields and try again.", "danger")
        else:
            email = form.orgEmailid.data
            org_name = form.orgName.data
            try:
                User.get(User.email == form.orgEmailid.data)
                flash(
                    "This Email address is already an Admin for one of the organisation",
                    "warning")
            except User.DoesNotExist:
                pass
            finally:
                # TODO: organisation can have mutiple admins:
                # TODO: user OrgAdmin
                try:
                    org = Organisation.get(name=org_name)
                    # TODO: fix it!
                    org.email = email
                except Organisation.DoesNotExist:
                    org = Organisation(name=org_name, email=email)
                org.save()

                try:
                    user = User.get(email=email)
                    user.roles |= Role.ADMIN
                    user.organisation = org
                except User.DoesNotExist:
                    user = User(
                        name=form.orgName.data,
                        email=form.orgEmailid.data,
                        confirmed=True,  # In order to let the user in...
                        roles=Role.ADMIN,
                        organisation=org)
                user.save()
                # Note: Using app context due to issue: https://github.com/mattupstate/flask-mail/issues/63
                with app.app_context():
                    msg = Message("Welcome to OrcidhHub",
                                  recipients=[str(form.orgEmailid.data)])
                    token = generate_confirmation_token(form.orgEmailid.data)
                    # TODO: do it with templates
                    msg.body = "Your organisation is just one step behind to get onboarded" \
                               " please click on following link to get onboarded " \
                               "https://" + environ.get("ENV", "dev") + ".orcidhub.org.nz" + \
                               url_for("confirm_organisation", token=token)
                    mail.send(msg)
                    flash(
                        "Organisation Onboarded Successfully!!! Email Communication has been sent to Admin",
                        "success")

    return render_template('registration.html', form=form)