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
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()
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)
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"))
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)