Beispiel #1
0
def add_or_edit_group():
    params = request.form if request.form else request.args
    if "group_name" in params:
        member_user_ids = set()
        admin_user_ids = set()
        admin_user_ids.add(
            g.user_session.user_id
        )  #ZS: Always add the user creating the group as an admin
        if "admin_emails_to_add" in params:
            admin_emails = params['admin_emails_to_add'].split(",")
            for email in admin_emails:
                user_details = get_user_by_unique_column(
                    "email_address", email)
                if user_details:
                    admin_user_ids.add(user_details['user_id'])
            #send_group_invites(params['group_id'], user_email_list = admin_emails, user_type="admins")
        if "member_emails_to_add" in params:
            member_emails = params['member_emails_to_add'].split(",")
            for email in member_emails:
                user_details = get_user_by_unique_column(
                    "email_address", email)
                if user_details:
                    member_user_ids.add(user_details['user_id'])
            #send_group_invites(params['group_id'], user_email_list = user_emails, user_type="members")

        create_group(list(admin_user_ids), list(member_user_ids),
                     params['group_name'])
        return redirect(url_for('manage_groups'))
    else:
        return render_template("admin/create_group.html")
Beispiel #2
0
def password_reset():
    """Entry point after user clicks link in E-mail"""
    logger.debug("in password_reset request.url is:", request.url)
    # We do this mainly just to assert that it's in proper form for displaying next page
    # Really not necessary but doesn't hurt
    # user_encode = DecodeUser(ForgotPasswordEmail.key_prefix).reencode_standalone()
    verification_code = request.args.get('code')
    hmac = request.args.get('hm')

    if verification_code:
        user_email = check_verification_code(verification_code)
        if user_email:
            user_details = get_user_by_unique_column('email_address',
                                                     user_email)
            if user_details:
                return render_template("new_security/password_reset.html",
                                       user_encode=user_details["user_id"])
            else:
                flash("Invalid code: User no longer exists!", "error")
        else:
            flash(
                "Invalid code: Password reset code does not exist or might have expired!",
                "error")
    else:
        return redirect(url_for("login"))
Beispiel #3
0
def send_group_invites(group_id, user_email_list=[], user_type="members"):
    for user_email in user_email_list:
        user_details = get_user_by_unique_column("email_address", user_email)
        if user_details:
            group_info = get_group_info(group_id)
            #ZS: Probably not necessary since the group should normally always exist if group_id is being passed here,
            #    but it's technically possible to hit it if Redis is cleared out before submitting the new users or something
            if group_info:
                #ZS: Don't add user if they're already an admin or if they're being added a regular user and are already a regular user,
                #    but do add them if they're a regular user and are added as an admin
                if (user_details['user_id'] in group_info['admins']) or \
                   ((user_type == "members") and (user_details['user_id'] in group_info['members'])):
                    continue
                else:
                    send_verification_email(
                        user_details,
                        template_name="email/group_verification.txt",
                        key_prefix="verification_code",
                        subject=
                        "You've been invited to join a GeneNetwork user group")
        else:
            temp_password = ''.join(
                random.choice(string.ascii_uppercase + string.digits)
                for _ in range(6))
            user_details = {
                'user_id': str(uuid.uuid4()),
                'email_address': user_email,
                'registration_info': basic_info(),
                'password': set_password(temp_password),
                'confirmed': 0
            }
            save_user(user_details, user_details['user_id'])
            send_invitation_email(user_email, temp_password)
def manage_resource():
    params = request.form if request.form else request.args
    if 'resource_id' in request.args:
        resource_id = request.args['resource_id']
        admin_status = check_owner_or_admin(resource_id=resource_id)

        resource_info = get_resource_info(resource_id)
        group_masks = resource_info['group_masks']
        group_masks_with_names = get_group_names(group_masks)
        default_mask = resource_info['default_mask']['data']
        owner_id = resource_info['owner_id']

        owner_display_name = None
        if owner_id != "none":
            owner_info = get_user_by_unique_column("user_id", owner_id)
            if 'name' in owner_info:
                owner_display_name = owner_info['full_name']
            elif 'user_name' in owner_info:
                owner_display_name = owner_info['user_name']
            elif 'email_address' in owner_info:
                owner_display_name = owner_info['email_address']

        return render_template("admin/manage_resource.html",
                               owner_name=owner_display_name,
                               resource_id=resource_id,
                               resource_info=resource_info,
                               default_mask=default_mask,
                               group_masks=group_masks_with_names,
                               admin_status=admin_status)
def manage_user():
    params = request.form if request.form else request.args
    if 'new_full_name' in params:
        set_user_attribute(g.user_session.user_id, 'full_name',
                           params['new_full_name'])
    if 'new_organization' in params:
        set_user_attribute(g.user_session.user_id, 'organization',
                           params['new_organization'])

    user_details = get_user_by_unique_column("user_id", g.user_session.user_id)

    return render_template("admin/manage_user.html", user_details=user_details)
Beispiel #6
0
def view_group():
    params = request.form if request.form else request.args
    group_id = params['id']
    group_info = get_group_info(group_id)
    admins_info = []
    user_is_admin = False
    if g.user_session.user_id in group_info['admins']:
        user_is_admin = True
    for user_id in group_info['admins']:
        if user_id:
            user_info = get_user_by_unique_column("user_id", user_id)
            admins_info.append(user_info)
    members_info = []
    for user_id in group_info['members']:
        if user_id:
            user_info = get_user_by_unique_column("user_id", user_id)
            members_info.append(user_info)

    #ZS: This whole part might not scale well with many resources
    resources_info = []
    all_resources = get_resources()
    for resource_id in all_resources:
        resource_info = get_resource_info(resource_id)
        group_masks = resource_info['group_masks']
        if group_id in group_masks:
            this_resource = {}
            privileges = group_masks[group_id]
            this_resource['id'] = resource_id
            this_resource['name'] = resource_info['name']
            this_resource['data'] = privileges['data']
            this_resource['metadata'] = privileges['metadata']
            this_resource['admin'] = privileges['admin']
            resources_info.append(this_resource)

    return render_template("admin/view_group.html",
                           group_info=group_info,
                           admins=admins_info,
                           members=members_info,
                           user_is_admin=user_is_admin,
                           resources=resources_info)
Beispiel #7
0
    def oauth2_login(self, login_type, user_id):
        """Login via an OAuth2 provider"""

        user_details = get_user_by_unique_column("user_id", user_id)
        if user_details:
            user = model.User()
            user.id = user_details["user_id"] if user_details[
                "user_id"] == None else "N/A"
            user.full_name = user_details["name"]
            user.login_type = user_details["login_type"]
            return self.actual_login(user)
        else:
            flash("Error logging in via OAuth2")
            return make_response(redirect(url_for('login')))
Beispiel #8
0
    def __init__(self, kw):
        self.thank_you_mode = False
        self.errors = []
        self.user = Bunch()

        self.user.email_address = kw.get('email_address',
                                         '').encode("utf-8").strip()
        if not (5 <= len(self.user.email_address) <= 50):
            self.errors.append(
                'Email Address needs to be between 5 and 50 characters.')
        else:
            email_exists = get_user_by_unique_column("email_address",
                                                     self.user.email_address)
            #email_exists = get_user_by_unique_column(es, "email_address", self.user.email_address)
            if email_exists:
                self.errors.append('User already exists with that email')

        self.user.full_name = kw.get('full_name', '').encode("utf-8").strip()
        if not (5 <= len(self.user.full_name) <= 50):
            self.errors.append(
                'Full Name needs to be between 5 and 50 characters.')

        self.user.organization = kw.get('organization',
                                        '').encode("utf-8").strip()
        if self.user.organization and not (5 <= len(self.user.organization) <=
                                           50):
            self.errors.append(
                'Organization needs to be empty or between 5 and 50 characters.'
            )

        password = str(kw.get('password', ''))
        if not (6 <= len(password)):
            self.errors.append('Password needs to be at least 6 characters.')

        if kw.get('password_confirm') != password:
            self.errors.append("Passwords don't match.")

        if self.errors:
            return

        logger.debug("No errors!")

        set_password(password, self.user)
        self.user.user_id = str(uuid.uuid4())
        self.user.confirmed = 1

        self.user.registration_info = json.dumps(basic_info(), sort_keys=True)
        save_user(self.user.__dict__, self.user.user_id)
Beispiel #9
0
def github_oauth2():
    from utility.tools import GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_AUTH_URL
    code = request.args.get("code")
    data = {
        "client_id": GITHUB_CLIENT_ID,
        "client_secret": GITHUB_CLIENT_SECRET,
        "code": code
    }

    result = requests.post("https://github.com/login/oauth/access_token",
                           json=data)
    result_dict = {
        arr[0]: arr[1]
        for arr in [
            tok.split("=") for tok in
            [token.encode("utf-8") for token in result.text.split("&")]
        ]
    }

    github_user = get_github_user_details(result_dict["access_token"])

    user_details = get_user_by_unique_column("github_id", github_user["id"])
    if user_details == None:
        user_details = {
            "user_id":
            str(uuid.uuid4()),
            "name":
            github_user["name"].encode("utf-8")
            if github_user["name"] else "None",
            "github_id":
            github_user["id"],
            "user_url":
            github_user["html_url"].encode("utf-8"),
            "login_type":
            "github",
            "organization":
            "",
            "active":
            1,
            "confirmed":
            1
        }
        save_user(user_details, user_details["user_id"])

    url = "/n/login?type=github&uid=" + user_details["user_id"]
    return redirect(url)
def orcid_oauth2():
    from uuid import uuid4
    from utility.tools import ORCID_CLIENT_ID, ORCID_CLIENT_SECRET, ORCID_TOKEN_URL, ORCID_AUTH_URL
    code = request.args.get("code")
    error = request.args.get("error")
    url = "/n/login"
    if code:
        data = {
            "client_id": ORCID_CLIENT_ID,
            "client_secret": ORCID_CLIENT_SECRET,
            "grant_type": "authorization_code",
            "redirect_uri": GN2_BRANCH_URL + "n/login/orcid_oauth2",
            "code": code
        }

        result = requests.post(ORCID_TOKEN_URL, data=data)
        result_dict = json.loads(result.text.encode("utf-8"))

        user_details = get_user_by_unique_column("orcid", result_dict["orcid"])
        if user_details == None:
            user_details = {
                "user_id":
                str(uuid4()),
                "name":
                result_dict["name"],
                "orcid":
                result_dict["orcid"],
                "user_url":
                "%s/%s" % ("/".join(
                    ORCID_AUTH_URL.split("/")[:-2]), result_dict["orcid"]),
                "login_type":
                "orcid",
                "organization":
                "",
                "active":
                1,
                "confirmed":
                1
            }
            save_user(user_details, user_details["user_id"])

        url = "/n/login?type=orcid&uid=" + user_details["user_id"]
    else:
        flash("There was an error getting code from ORCID")
    return redirect(url)
def register_user(params):
    thank_you_mode = False
    errors = []
    user_details = {}

    user_details['email_address'] = params.get('email_address',
                                               '').encode("utf-8").strip()
    if not (5 <= len(user_details['email_address']) <= 50):
        errors.append('Email Address needs to be between 5 and 50 characters.')
    else:
        email_exists = get_user_by_unique_column("email_address",
                                                 user_details['email_address'])
        if email_exists:
            errors.append('User already exists with that email')

    user_details['full_name'] = params.get('full_name',
                                           '').encode("utf-8").strip()
    if not (5 <= len(user_details['full_name']) <= 50):
        errors.append('Full Name needs to be between 5 and 50 characters.')

    user_details['organization'] = params.get('organization',
                                              '').encode("utf-8").strip()
    if user_details['organization'] and not (5 <= len(
            user_details['organization']) <= 50):
        errors.append(
            'Organization needs to be empty or between 5 and 50 characters.')

    password = str(params.get('password', ''))
    if not (6 <= len(password)):
        errors.append('Password needs to be at least 6 characters.')

    if params.get('password_confirm') != password:
        errors.append("Passwords don't match.")

    user_details['password'] = set_password(password)
    user_details['user_id'] = str(uuid.uuid4())
    user_details['confirmed'] = 1

    user_details['registration_info'] = basic_info()

    if len(errors) == 0:
        save_user(user_details, user_details['user_id'])

    return errors
Beispiel #12
0
def forgot_password_submit():
    """When a forgotten password form is submitted we get here"""
    params = request.form
    email_address = params['email_address']
    next_page = None
    if email_address != "":
        logger.debug("Wants to send password E-mail to ", email_address)
        user_details = get_user_by_unique_column("email_address",
                                                 email_address)
        if user_details:
            ForgotPasswordEmail(user_details["email_address"])
            return render_template("new_security/forgot_password_step2.html",
                                   subject=ForgotPasswordEmail.subject)
        else:
            flash("The e-mail entered is not associated with an account.",
                  "alert-danger")
            return redirect(url_for("forgot_password"))

    else:
        flash("You MUST provide an email", "alert-danger")
        return redirect(url_for("forgot_password"))
Beispiel #13
0
def password_reset():
    """Entry point after user clicks link in E-mail"""
    logger.debug("in password_reset request.url is:", request.url)

    verification_code = request.args.get('code')
    hmac = request.args.get('hm')

    if verification_code:
        user_email = check_verification_code(verification_code)
        if user_email:
            user_details = get_user_by_unique_column('email_address',
                                                     user_email)
            if user_details:
                return render_template(
                    "new_security/password_reset.html",
                    user_encode=user_details["email_address"])
            else:
                flash("Invalid code: User no longer exists!", "error")
        else:
            flash(
                "Invalid code: Password reset code does not exist or might have expired!",
                "error")
    else:
        return redirect(url_for("login"))
Beispiel #14
0
    def standard_login(self):
        """Login through the normal form"""
        params = request.form if request.form else request.args
        logger.debug("in login params are:", params)

        if not params:
            from utility.tools import GITHUB_AUTH_URL, GITHUB_CLIENT_ID, ORCID_AUTH_URL, ORCID_CLIENT_ID
            external_login = {}
            if GITHUB_AUTH_URL and GITHUB_CLIENT_ID != 'UNKNOWN':
                external_login["github"] = GITHUB_AUTH_URL
            if ORCID_AUTH_URL and ORCID_CLIENT_ID != 'UNKNOWN':
                external_login["orcid"] = ORCID_AUTH_URL

            return render_template("new_security/login_user.html",
                                   external_login=external_login,
                                   redis_is_available=is_redis_available())
        else:
            user_details = get_user_by_unique_column("email_address",
                                                     params["email_address"])
            #user_details = get_user_by_unique_column(es, "email_address", params["email_address"])
            user = None
            valid = None
            if user_details:
                user = model.User()
                for key in user_details:
                    user.__dict__[key] = user_details[key]
                valid = False

                submitted_password = params['password']
                pwfields = Struct(json.loads(user.password))
                encrypted = Password(submitted_password, pwfields.salt,
                                     pwfields.iterations, pwfields.keylength,
                                     pwfields.hashfunc)
                logger.debug("\n\nComparing:\n{}\n{}\n".format(
                    encrypted.password, pwfields.password))
                valid = pbkdf2.safe_str_cmp(encrypted.password,
                                            pwfields.password)
                logger.debug("valid is:", valid)

        if valid and not user.confirmed:
            VerificationEmail(user)
            return render_template(
                "new_security/verification_still_needed.html",
                subject=VerificationEmail.subject)
        if valid:
            if params.get('remember'):
                logger.debug("I will remember you")
                self.remember_me = True

            if 'import_collections' in params:
                import_col = "true"
            else:
                import_col = "false"

            #g.cookie_session.import_traits_to_user()

            self.logged_in = True

            return self.actual_login(user, import_collections=import_col)

        else:
            if user:
                self.unsuccessful_login(user)
            flash("Invalid email-address or password. Please try again.",
                  "alert-danger")
            response = make_response(redirect(url_for('login')))

            return response
def login():
    params = request.form if request.form else request.args
    logger.debug("in login params are:", params)

    if not params:  #ZS: If coming to page for first time
        from utility.tools import GITHUB_AUTH_URL, GITHUB_CLIENT_ID, ORCID_AUTH_URL, ORCID_CLIENT_ID
        external_login = {}
        if GITHUB_AUTH_URL and GITHUB_CLIENT_ID != 'UNKNOWN':
            external_login["github"] = GITHUB_AUTH_URL
        if ORCID_AUTH_URL and ORCID_CLIENT_ID != 'UNKNOWN':
            external_login["orcid"] = ORCID_AUTH_URL
        return render_template("new_security/login_user.html",
                               external_login=external_login,
                               redis_is_available=is_redis_available())
    else:  #ZS: After clicking sign-in
        if 'type' in params and 'uid' in params:
            user_details = get_user_by_unique_column("user_id", params['uid'])
            if user_details:
                session_id_signed = get_signed_session_id(user_details)
                if 'name' in user_details and user_details['name'] != "None":
                    display_id = user_details['name']
                elif 'github_id' in user_details:
                    display_id = user_details['github_id']
                elif 'orcid' in user_details:
                    display_id = user_details['orcid']
                else:
                    display_id = ""
                flash("Thank you for logging in {}.".format(display_id),
                      "alert-success")
                response = make_response(redirect(url_for('index_page')))
                response.set_cookie(UserSession.user_cookie_name,
                                    session_id_signed,
                                    max_age=None)
            else:
                flash("Something went unexpectedly wrong.", "alert-danger")
                response = make_response(redirect(url_for('index_page')))
            return response
        else:
            user_details = get_user_by_unique_column("email_address",
                                                     params['email_address'])
            password_match = False
            if user_details:
                submitted_password = params['password']
                pwfields = user_details['password']
                if isinstance(pwfields, str):
                    pwfields = json.loads(pwfields)
                encrypted_pass_fields = encode_password(
                    pwfields, submitted_password)
                password_match = pbkdf2.safe_str_cmp(
                    encrypted_pass_fields['password'], pwfields['password'])

            else:  # Invalid e-mail
                flash("Invalid e-mail address. Please try again.",
                      "alert-danger")
                response = make_response(redirect(url_for('login')))

                return response
            if password_match:  # If password correct
                if user_details['confirmed']:  # If account confirmed
                    import_col = "false"
                    anon_id = ""
                    if 'import_collections' in params:
                        import_col = "true"
                        anon_id = params['anon_id']

                    session_id_signed = get_signed_session_id(user_details)
                    flash(
                        "Thank you for logging in {}.".format(
                            user_details['full_name']), "alert-success")
                    response = make_response(
                        redirect(
                            url_for('index_page',
                                    import_collections=import_col,
                                    anon_id=anon_id)))
                    response.set_cookie(UserSession.user_cookie_name,
                                        session_id_signed,
                                        max_age=None)
                    return response
                else:
                    email_ob = send_verification_email(
                        user_details,
                        template_name="email/user_verification.txt")
                    return render_template(
                        "newsecurity/verification_still_needed.html",
                        subject=email_ob['subject'])
            else:  # Incorrect password
                #ZS: It previously seemed to store that there was an incorrect log-in attempt here, but it did so in the MySQL DB so this might need to be reproduced with Redis
                flash("Invalid password. Please try again.", "alert-danger")
                response = make_response(redirect(url_for('login')))

                return response