def request_reset_password(): if request.env.request_method == 'POST': import datetime email = request.vars.email if email: # Check the email existence on the database valid_email = db(db.user.email == email).select().first() if not valid_email: session.flash = 'No user with email %s found!' % email redirect(URL('user', 'request_reset_password')) # If there is registation key, user has not yet activated the account. registration_key = valid_email.registration_key # Check the user account activation via registration key. if registration_key: session.flash = 'Password reset not allowed: Your registration is pending, please check the email to activate the account' redirect(URL('user', 'request_reset_password')) expiration = valid_email.expiration today_date = datetime.datetime.today() # Check the expiration has given to the account and with current date if expiration and expiration < today_date: session.flash = "Your account has expired. Please contact your account administrator for details." redirect(URL('user', 'request_reset_password')) return dict(form=auth.request_reset_password(next=URL('user', 'request_reset_password')))
def set_new_password(): """ Get registration key from URL params Get user email from request params If user in db has matching registration key, allow current user to set new password If user password matches, Set password, then redirect to login screen with message confirming new password change else, return error message """ registration_key = request.vars.registration_key email = request.vars.email password1 = request.vars.password1 or '' password2 = request.vars.password2 or '' # validate password for Caps, Number, and 8-char length is_valid_password = len(re.findall(r'[A-Z]', password1)) and len(re.findall(r'[0-9]', password1)) and ( len(password1) > 7) user = db(db.user.email == email).select().first() if not user: session.flash = 'No user with email %s found!' % email redirect(URL('user', 'login')) elif user.registration_key == registration_key and user.registration_key: if not password1 or not password2: # user hasn't submitted their password return dict(registration_key=registration_key, email=email) elif not is_valid_password: response.flash = 'Password is not valid: please follow the password requirements listed below.' return dict(registration_key=registration_key, email=email) elif password1 == password2: password = hash_password(password1) user.update_record(password=password, registration_key='') # redirect to login page, tell them their new password has been set. session.flash = 'New password saved! Please login to continue.' redirect(URL('user', 'login')) else: # passwords don't match, return error message telling them their passwords don't match response.flash = 'Your passwords must match! Please re-enter them below.' return dict(registration_key=registration_key, email=email) else: # redirect user to login form, tell them their registration key is incorrect session.flash = 'Your registration key is incorrect!' redirect(URL('user', 'login')) return dict()
def add_social_network(): """ An SQL form which stores the information related to a social network. Admin can provide data like client_key, secret_key, redirect_url in this form to be saved in db table social_network :return: """ form = SQLFORM(db.social_network) # form['_style'] = 'border:1px solid black; color:#000000' form['_class'] = 'table form-horizontal' form.add_button('Manage Social Networks', URL('user', 'manage_social_network')) if form.process().accepted: link = form.vars['redirectUrl'] form_data = {'vendorId': form.vars['vendorId'], 'clientKey': form.vars['clientKey'], 'appUrl': form.vars['appUrl'], 'redirectUrl': form.vars['redirectUrl'], 'authUrl': form.vars['authUrl']} session.form_data = form_data redirect(link) elif form.errors: response.flash = 'Form has errors!' else: response.flash = 'Please fill out the form...' return dict(form=form)
def impersonate(): if request.args: impersonated_id = request.args[0] if not auth.has_permission('impersonate', db.user, impersonated_id): auth.add_permission(1, 'impersonate', db.user, impersonated_id) auth.impersonate(user_id=impersonated_id) redirect(URL('dashboard', 'index')) return dict()
def dice_oauth_callback(): """ Callback for the implicit flow: https://tools.ietf.org/html/rfc6749#section-4.2.2 Inputs: access_token, refresh_token, token_type, user_id. If no getTalent user exists with the given Dice user_id or email address, will auto-create the user & domain. Then, log them in. If a getTalent user is found with the given email but does not have a Dice ID, will still log them in. """ # Input validation access_token = request.vars.access_token refresh_token = request.vars.refresh_token token_type = request.vars.token_type dice_user_id = request.vars.user_id dice_env = request.vars.environment or 'prod' if not access_token or not refresh_token or not token_type or not dice_user_id: email_error_to_admins(body="Received a request to dice_oauth_callback with missing parameter", subject="dice_oauth_callback: Missing input") redirect("https://www.gettalent.com") # Query Dice API for user info from TalentDiceClient import query_dice_user_id user_info = query_dice_user_id(dice_user_id=dice_user_id, dice_access_token=access_token, dice_refresh_token=refresh_token, dice_env=dice_env) if not user_info: logger.error("dice_oauth_callback(%s): Failed to query Dice API", request.vars) email_error_to_admins(body="Failed to query Dice API during dice_oauth_callback. See error logs for details", subject="dice_oauth_callback: Querying Dice API") redirect("https://www.gettalent.com") dice_company_id = user_info['dice_company_id'] first_name = user_info['first_name'] last_name = user_info['last_name'] email = user_info['email'] # Get or create the user from TalentUsers import get_or_create_dice_user user_row = get_or_create_dice_user(email, first_name, last_name, dice_user_id, dice_company_id, access_token, refresh_token, dice_env=dice_env) if user_row: # Log in user & go to Dashboard logger.info("Logging in user %s from Dice", user_row.email) auth.login_and_set_dice_tokens(user_row, access_token, refresh_token) redirect(URL('web', 'dashboard', 'index')) return dict(message='Success') else: # If user unknown or user creation failed, redirect to gettalent.com logger.error("dice_oauth_callback(request.vars=%s): User creation failed", request.vars) email_error_to_admins(body="User auto-creation failed in dice_oauth_callback", subject="dice_oauth_callback: Auto-create user") redirect("https://www.gettalent.com")
def reset_password(): return dict(form=auth.reset_password(next=URL('dashboard', 'index')))
def login(): if auth.is_logged_in(): redirect(URL('dashboard', 'index', host=True)) response.title = "Login" response.files.append(URL('static', 'js/jquery.reject.js')) response.files.append(URL('static', 'css/jquery.reject.css')) # noinspection PyUnusedLocal,PyProtectedMember def email_widget(field, value): return INPUT(_name=field.name, _id="%s_%s" % (field._tablename, field.name), _class="span12", _type="text", _placeholder="Email Address", requires=field.requires) db.user.email.widget = email_widget # noinspection PyProtectedMember,PyUnusedLocal def password_widget(field, value): return INPUT(_name=field.name, _id="%s_%s" % (field._tablename, field.name), _class="span12", _placeholder="Password", _type="password", requires=field.requires) db.user.password.widget = password_widget if request.vars.email and request.vars.password: email = request.vars.email.strip() if auth.login_bare(request.vars.email, request.vars.password): user = db(db.user.email == email).select(db.user.ALL).first() # Get Bearer Token from Talent AuthService import requests params = dict(grant_type="password", username=request.vars.email, password=request.vars.password) try: auth_service_token_response = requests.post(current.OAUTH_SERVER, params=params, auth=(current.OAUTH_CLIENT_ID, current.OAUTH_CLIENT_SECRET)).json() if not (auth_service_token_response.get(u'access_token') and auth_service_token_response.get(u'refresh_token')): logger.error("Either Access Token or Refresh Token is missing") else: from TalentUsers import store_auth_service_tokens_in_session store_auth_service_tokens_in_session(auth_service_token_response) except Exception as e: logger.exception("Couldn't get Bearer Token, %s" % e.message) # Check to see if user has already expired if user.expiration and user.expiration < datetime.datetime.now(): session.auth = None session.flash = 'Your account has expired. Please contact your account administrator for details.' redirect(URL('user', 'login')) return dict() web_auth_cas = db(db.web_auth_cas.user_id == user.id).select().first() if not web_auth_cas: # Make new entry in auth_cas table ticket = "ST-" + web2py_uuid() db.web_auth_cas.update_or_insert(db.web_auth_cas.user_id == user.id, user_id=user.id, service='talent_web', ticket=ticket, renew='T') else: # Try logging in with Dice auth.dice_login_bare(email, request.vars.password) next_login = request.get_vars._next or URL('dashboard', 'index') form = auth.login(next=next_login) return dict(form=form)
def profile(): response.title = "Profile" if request.vars._formname == 'widget_page': existing_widget_page = db.widget_page(request.vars.id) existing_widget_page.update_record( replyAddress=request.vars.replyAddress, emailSource='"%s" <*****@*****.**>' % request.vars.emailSource, welcomeEmailSubject=request.vars.welcomeEmailSubject, welcomeEmailHtml=request.vars.welcomeEmailHtml, requestEmailHtml=request.vars.requestEmailHtml ) response.flash = 'Widget settings updated' custom_fields = None if request.vars._formname == 'custom_fields': custom_fields = db(db.custom_field.domainId == auth.user.domainId).select(cache=(cache.ram, 300)) current_custom_field_names = [row.name.strip() for row in custom_fields] # Convert custom field names & types to array if it's string new_custom_field_names = request.vars.get('custom_field.name') if isinstance(new_custom_field_names, basestring): new_custom_field_names = [new_custom_field_names] new_custom_field_types = request.vars.get('custom_field.type') if isinstance(new_custom_field_types, basestring): new_custom_field_types = [new_custom_field_types] new_custom_field_cats = request.vars.get('custom_field.category') if isinstance(new_custom_field_cats, int): new_custom_field_cats = [new_custom_field_cats] # Strip the names new_custom_field_names = [name.strip() for name in new_custom_field_names] # Make dict of new custom field name -> type new_name_to_type = dict() new_name_to_cat = dict() for index, new_custom_field_name in enumerate(new_custom_field_names): cf_type = new_custom_field_types[index] cat = new_custom_field_cats[index] new_name_to_type[new_custom_field_name] = cf_type if cf_type in ('string', 'datetime') else 'string' new_name_to_cat[new_custom_field_name] = int(cat) or None # Add in custom fields unless one with the same name already exists # hmm, can it be same name with different category ? and could not be done at the moment unless custom-field id comes back from solr @TODO refresh_custom_fields_cache = True for index, new_name in enumerate(new_custom_field_names): if new_name and new_name not in current_custom_field_names: db.custom_field.insert(domainId=auth.user.domainId, name=new_name, type=new_name_to_type[new_name], categoryId=new_name_to_cat[new_name]) refresh_custom_fields_cache = True elif new_name and new_name in current_custom_field_names: db((db.custom_field.name == new_name) & (db.custom_field.domainId == auth.user.domainId)).update( categoryId=new_name_to_cat[new_name]) if refresh_custom_fields_cache: custom_fields = db(db.custom_field.domainId == auth.user.domainId).select(cache=(cache.ram, 0)) # there's a bug in the change_password function in web2py - redirects before returning an error if request.vars.old_password and request.vars.new_password and request.vars.new_password2: if not auth.login_bare(auth.user.email, request.vars.old_password): request.vars.old_password = '' request.vars.new_password = '' request.vars.new_password2 = '' session.flash = 'Your old password is not correct. Please try again.' form = auth.change_password(next=URL('user', 'profile')) # Get custom fields & the # of candidates in each field if not custom_fields: custom_fields = db(db.custom_field.domainId == auth.user.domainId).select(cache=(cache.ram, 300)) custom_field_ids = [row.id for row in custom_fields] count = db.candidate_custom_field.id.count() candidate_custom_field_counts = db( db.candidate_custom_field.customFieldId.belongs(custom_field_ids) ).select(db.candidate_custom_field.ALL, count, groupby=db.candidate_custom_field.customFieldId) # find what values are assigned to each custom field count_values = db.candidate_custom_field.value.count() custom_fields_values = db( db.candidate_custom_field.customFieldId.belongs(custom_field_ids) ).select(count_values, db.candidate_custom_field.customFieldId, db.candidate_custom_field.value, groupby=db.candidate_custom_field.value) for custom_field in custom_fields: candidate_custom_field = candidate_custom_field_counts.find( lambda cf_row: cf_row.candidate_custom_field.customFieldId == custom_field.id).first() custom_field.num_candidates = candidate_custom_field[count] if candidate_custom_field else 0 # Default Tracking Code domain = db.domain(auth.user.domainId) if request.vars._formname == 'email_marketing': domain.update_record(defaultTrackingCode=request.vars.tracking_code, defaultFromName=request.vars.default_from_name) tracking_code = domain.defaultTrackingCode default_from_name = domain.defaultFromName # user is a Talent Customer admin(customer management tab) if auth.has_membership(group_id=1): domain_data = db().select(db.domain.id, db.domain.name) domain_ids = [row.id for row in domain_data] is_talent_admin = True else: domain_data = db(db.domain.id == auth.user.domainId).select(db.domain.id, db.domain.name) domain_ids = [auth.user.domainId] is_talent_admin = False customer_data = db(db.domain.id.belongs(domain_ids)).select(db.user.id, db.user.email, db.user.firstName, db.user.lastName, db.user.addedTime, db.user.expiration, db.user_attributes.brand, db.user_attributes.department, db.user_attributes.userGroup, db.user_attributes.KPI, db.candidate.id.count(), db.user.domainId, groupby=db.user.id, orderby=(~db.domain.addedTime), left=[ db.candidate.on( db.user.id == db.candidate.ownerUserId), db.domain.on(db.user.domainId == db.domain.id), db.user_attributes.on( db.user.id == db.user_attributes.userId), ] ) last_login_data = db.executesql("""SELECT * FROM (SELECT web_auth_event.time_stamp, web_auth_event.user_id FROM web_auth_event WHERE (web_auth_event.description LIKE '% Logged-in') ORDER BY web_auth_event.time_stamp DESC) as temp GROUP BY user_id;""", as_dict=True) user_admin_data = db(db.web_auth_membership.group_id == 2).select(db.web_auth_membership.user_id, db.web_auth_membership.group_id) last_logins = {} for row in last_login_data: last_login = row.get('time_stamp').strftime("%D") if row.get('time_stamp') else 'Never' last_logins.setdefault(row.get('user_id'), last_login) dashboard_data = [] for domain in domain_data: dashboard_row = {'domain': domain.name} domain_users = customer_data.find(lambda cd_row: cd_row.user.domainId == domain.id) domain_candidate_count = 0 for user in domain_users: account_type = user_admin_data.find(lambda uad_row: uad_row.user_id == user.user.id) domain_candidate_count += int(user['_extra']["COUNT(candidate.id)"]) user.user['last_login'] = last_logins.get(user.user.id) user.user['addedTime'] = user.user.addedTime.strftime("%D") user.user['expiration'] = user.user.expiration.strftime("%D") if user.user.expiration else '' user.user['account_type'] = 'Admin' if len(account_type) else 'Normal' dashboard_row['candidate_count'] = domain_candidate_count dashboard_row['users'] = domain_users dashboard_data.append(dashboard_row) from TalentUsers import is_current_user_admin is_company_admin = is_current_user_admin() widget_pages = db(db.user.domainId == auth.user.domainId)(db.widget_page.userId == db.user.id).select( db.widget_page.ALL) candidate_source_ids = [wp.candidateSourceId for wp in widget_pages] # In case widget has no candidate_source_ids if None in candidate_source_ids: candidate_source_ids = [] logger.error("A widget_page did not have a candidate_source_id: domainId=%s", auth.user.domainId) candidate_sources = db(db.candidate_source.id.belongs(candidate_source_ids)).select() if candidate_sources: widget_page = widget_pages.find( lambda widget_page_row: widget_page_row.candidateSourceId == candidate_sources.first().id).first() else: widget_page = get_or_create_widget_page(auth.user) # All custom fields in logged-in user's domain from TalentUsers import RATING_CATEGORY_NAME, get_or_create_rating_custom_fields get_or_create_rating_custom_fields(auth.user.domainId) domain_custom_fields = db(db.custom_field_category.domainId == auth.user.domainId).select( db.custom_field_category.ALL) # custom fields categories rating_category = domain_custom_fields.find(lambda cf_cat: cf_cat.name == RATING_CATEGORY_NAME).first() custom_fields_categories = domain_custom_fields.find(lambda cf_cat: cf_cat.name != RATING_CATEGORY_NAME) # Remove rating related fields from custom_fields, Rating will have separate UI. custom_fields_without_ratings = custom_fields.find(lambda cf: cf.categoryId != rating_category.id) # Custom fields for rating rating_custom_fields = custom_fields.find(lambda cf: cf.categoryId == rating_category.id) # areas of interest parents areas_of_interest_parents = db((db.area_of_interest.domainId == auth.user.domainId) & ( (db.area_of_interest.parentId == None) | (db.area_of_interest.parentId == 0))).select(db.area_of_interest.id, db.area_of_interest.description) # custom layout mode check domain_settings = get_domain_settings_dict(db.domain(auth.user.domainId)) current_layout_mode = domain_settings.get('layoutMode', 0) social_network_info = db(db.social_network.authUrl != None).select(db.social_network.name, db.social_network.clientKey, db.social_network.authUrl, db.social_network.redirectUri) return dict( social_network_info=social_network_info, form=form, widget_page=widget_page, custom_fields=custom_fields_without_ratings, candidate_custom_field_counts=candidate_custom_field_counts, tracking_code=tracking_code, default_from_name=default_from_name, domains=domain_data, dashboard_data=dashboard_data, is_gettalent_admin=is_talent_admin, is_company_admin=is_company_admin, candidate_sources=candidate_sources, custom_fields_categories=custom_fields_categories, areas_of_interest_parents=areas_of_interest_parents, current_layout_mode=current_layout_mode, custom_fields_values=custom_fields_values, count_values=count_values, rating_custom_fields=rating_custom_fields )