def settings_view(request): settings_all = dict(DBSession.query(Settings.key, Settings).all()) if request.method == 'POST': for key, value in request.POST.iteritems(): if 'drive_id' in key: settings_all[key[:-9]].drive_id = value elif key in settings_all: settings_all[key].value = value Settings.set_docs_vals(settings_all) Settings._cache = {} get_region('main').invalidate() settings = {} settings['urls'], settings['general'], settings['drive_ids'] = [{} for x in range(3)] for k, v in settings_all.iteritems(): if 'http' in v.value: settings['urls'][k] = v.value if 'google' in v.value or v.drive_id: settings['drive_ids'][k] = v.drive_id or '' else: settings['general'][k] = v.value return { 'settings_general': settings['general'], 'settings_urls': settings['urls'], 'settings_drive_ids': settings['drive_ids'] }
def forbidden_view(request): home_redirect = Settings.get('home_redirect') if request.authenticated_userid: url = home_redirect or '/' if request.user and request.user.primary_type: url = Settings.get('redirect_%s' % request.user.primary_type, url) or url return HTTPFound(location=url) loc = '/login?came_from=%s' % request.path return HTTPFound(location=loc)
def find_gdocs(request): query = request.params.get('query', '') docs = [] if not query.strip(): return docs global docs_img_cache global docs_cache fields = 'items(alternateLink,defaultOpenWithLink,title,thumbnailLink,iconLink)' sq = "(title contains '%(query)s' or fullText contains '%(query)s') and trashed=false" % {'query': query} owners = ["'%s' in owners" % owner for owner in Settings.get('gdocs_allowed_owners').split(',')] sq += "and (%s)" % (' or '.join(owners)) max_docs = int(Settings.get('gdocs_max')) rq = 'https://www.googleapis.com/drive/v2/files?%s' % urlencode({'fields': fields, 'q': sq, 'maxResults': max_docs}) resp = None docs = docs_cache.get(query, []) http = None if not docs: try: http = getGoogleApiHttp(Settings.get('gdocs_user')) resp = http.request(rq) json_resp = simplejson.loads(resp[1]) docs = json_resp['items'] if len(docs_cache) > 20: docs_cache = {} docs_cache[query] = docs except: logging.error('could not get parsable json response from google! Resp: %s' % resp, exc_info=1) new_cache = {} for i in docs: thumblink = i.get('thumbnailLink') our_image = docs_img_cache.get(thumblink) if not our_image and thumblink: try: if not http: http = getGoogleApiHttp(Settings.get('gdocs_user')) resp = http.request(thumblink) if resp[0]['status'] == '200': new_cache[thumblink] = resp[1] except: pass our_image = new_cache[thumblink] if our_image: i['our_image'] = base64.encodestring(our_image) if len(docs_img_cache) + len(new_cache) > 50: docs_img_cache = {} if new_cache: docs_img_cache.update(new_cache) return {'docs': docs}
def forbidden_view(request): home_redirect = Settings.get('home_redirect') if request.authenticated_userid: url = home_redirect or '/' if request.user and request.user.primary_type and request.user.login_enabled: url = Settings.get('redirect_%s' % request.user.primary_type, url) or url if url not in (request.referer or request.url): if 'logout' in url and request.user.is_admin: url = Settings.get('home_redirect', '/') return HTTPFound(location=url) return HTTPFound('/logout?no_redirect=1') loc = '/login?came_from=%s' % request.path return HTTPFound(location=loc)
def handle_if_company(k, v, required=True, request=False): from alchemist.models.base import DBSession from alchemist.models.company import BaseCompany from alchemist.models.settings import Settings if k in ['company', 'company_id']: is_name = False try: company_id = int(v) company = DBSession.query(BaseCompany).get(company_id) except: v = v.replace(new_company_text, '') company = DBSession.query(BaseCompany).filter(BaseCompany.name == v).first() if not company: company = DBSession.query(BaseCompany).filter(BaseCompany.name.startswith(v.strip())).first() is_name = True assert not required or company, 'The company does not exist.' if not company and is_name: company = BaseCompany() company.name = v if request and request.referer and 'add/founder' in request.referer: company.is_alchemist = True company.alchemistclass = int(Settings.get('alchemistclass')) company.companytype = 'startup' DBSession.add(company) DBSession.flush() return company.id if k == 'company_id' else company return v
def program_resources(request): if 'all_ids' in request.session: del request.session['all_ids'] if 'search_query' in request.session: del request.session['search_query'] if 'current_page' in request.session: del request.session['current_page'] gdrive_items = Settings.get_gdocs() return {'gdrive_items': gdrive_items}
def user_remove_account_request(request): user = User.fr(request) admin_mail = Settings.get('admin_mail').split(',')[0] send_mail(admin_mail, 'remove_account_request', request, {'username': user._email, 'application_url': request.application_url, 'user_type': user.type.split(',')[-1], 'user_id': user.id}) return HTTPFound('/%s/%s' % (user.type.split(',')[-1], user.id))
def add_user_view(request): utype = request.matchdict.get('type') user = {'type': utype} company_match = False if request.method == 'POST': try: user = User() for k, v in request.POST.iteritems(): if v == 'on': v = True v = {'true': True, 'false': False}.get(v, v) v = Tag.handle_if_tags(k, v) if k == 'company_id' or k == 'company': try: company_match = getattr(request.user, k) == int(v) except: company_match = request.user.company.name == v.strip() if request.user.company else False v = v.replace(' - Add new company', '') assert company_match or request.user.is_admin, \ 'You just tried to add an user to a company You don\'t have access to. You can\'t do that!' k = 'company' v = handle_if_company(k, v, required=False, request=request) v = handle_file_save('%s_adm_cr_%s' % (getattr(user, 'nicename', user.id), request.authenticated_userid), v) setattr(user, k, v) plain_pass, _ = gen_ver_code(user.nicename) user.password = plain_pass user.activated = True user.login_enabled = False user.primary_type = utype if not user.username: user.username = user.email _, user.ver_code = gen_ver_code('signup_%s' % user.id) DBSession.add(user) DBSession.flush() admin_emails = Settings.get('admin_mail') send_mail(admin_emails, 'roleadd', request, {'user': user, 'new_role': utype}) user.send_mail('invite', request, {'plain_pass': plain_pass, 'user_id': user.id, 'hash': user.ver_code}) request.session.flash('Successfully added a new %s' % ( 'Team Member' if company_match else str(user.primary_type).capitalize())) url = '/%s/%s' % (user.primary_type, user.id) return HTTPFound(url) except Exception, e: request.session.flash('Error: %s' % e.message, 'error') if request.referer: return HTTPFound(request.referer) raise
def oauthcallback_view(request): flow = get_oauth_flow_linkedin(request) error = request.params.get('error') if not request.params.get('code') or error: if error != 'access_denied': request.session.flash('%s - %s' % (request.params.get('error_description'), error), 'error') return HTTPFound('/logout?no_redirect=1') return HTTPFound(Settings.get('after_register_redirect')) try: check_csrf_token(request, token='state') except BadCSRFToken: return user_login_view(request) try: credentials = flow.step2_exchange(request.params.get('code')) except FlowExchangeError: return user_login_view(request) resp = requests.get('https://api.linkedin.com/v1/people/~:(id,email-address)?format=json', headers={'Authorization': 'Bearer %s' % credentials.access_token}) if resp and resp.json: try: email = resp.json.get('emailAddress', '').strip() lin_id = resp.json['id'] except: json = resp.json() email = json.get('emailAddress', '').strip() lin_id = json.get('id') if not email: logging.warning('OAuth did not receive email, received: %s' % resp.json) if email and request.authenticated_userid: from alchemist.auth.confirm_acc import complete_confirm_acc return complete_confirm_acc(email, request) user = DBSession.query(User).filter(or_(User._email.contains(email), User.linkedin_email.contains(email))).first() if user and user.login_enabled: remember(request, user.id) try: user.last_login = datetime.now() except: logging.warning('Failed to update last_login time') return redirect_check_first_login('/', request, user) else: admin_mail = ((Settings.get('admin_mail') or '').split(',')[0].strip()) if not user: logging.error('OAuth did not find user for id:%s, email:%s' % (lin_id, email)) try: if Settings.get('admin_mail'): send_mail(Settings.get('admin_mail'), 'linkedinlogin', request, {'id': lin_id, 'email': email}) except: logging.error('Failed to send admin notice about failed login') try: credentials.revoke(httplib2.Http()) except: credentials.invalid = True if credentials.store: credentials.store.delete() message_data = {'admin': admin_mail, 'linkedin_conf': Settings.get('linkedin_email_conf_url'), 'email': email} request.session.flash((USER_INACTIVE_MESSAGE if user else NO_USER_MESSAGE) % message_data, 'error') request.session.new_csrf_token() return HTTPFound('/logout?no_redirect=1') return HTTPFound('/logout')
def send_mail(to, etype, request, data=None): add_cc = ['mentoring_request', 'mentoring_request_intro'] if data is None: data = {} mi = emails.get(etype, 'data').copy() if mi.get('mailer'): mailer = mailer_factory_from_settings(mi.get('mailer'), '') else: mailer = get_mailer(request) if 'user' not in data: from alchemist.models import User data['user'] = User.fr(request) if request.authenticated_userid and data['user'].id != request.authenticated_userid: from alchemist.models import User data['auth_user'] = User.fr(request) for k, v in mi.iteritems(): if callable(v): v = v(data, request) if '/templates/' in v: v = render(v, data, request) elif isinstance(v, basestring): if '{{' in v and '}}' in v: v = Template(v).render(**data) else: v = v.format(**data) mi[k] = v if 'attachments' in data: attachments = data['attachments'] elif 'attachments' in mi and mi['attachments'] and mi['attachments'] != 'None': with open(os.path.dirname(__file__) + mi['attachments']) as fo: a_file = fo.read() attachments = [Attachment(os.path.basename(mi['attachments']), 'application/' + mi['attachments'][-3:], a_file)] else: attachments = None if not isinstance(to, list): to = to.split(',') from alchemist.models.settings import Settings send_from = mi.get('from') bcc = [bc for bc in mi.get('bcc', '').split(',') if bc] sender = Settings.get('admin_mail', '*****@*****.**') sender = sender.split(',') main_admin_mail = sender[0].strip() if main_admin_mail: bcc.append(main_admin_mail) if not send_from: send_from = main_admin_mail or '*****@*****.**' cc = mi.get('cc') if mi.get('cc') else [] if '@' not in cc and not isinstance(cc, list): cc = Settings.get(cc, cc).split(',') if not cc and etype in add_cc: cc = [email.strip() for email in Settings.get('cc_emails', '').split(',')] mail = Message(mi['subject'], to, mi['text'], mi['html'], sender=send_from, bcc=bcc, cc=cc) if attachments: mail.attachments = attachments mailer.send(mail)
def user_remove_company_request(request): company = request.user.company admin_mail = Settings.get('admin_mail').split(',')[0] send_mail(admin_mail, 'remove_company_request', request, {'company_name': company.name, 'application_url': request.referrer}) return HTTPFound('/company/%s' % (company.id))
def logout_view(request): if request.authenticated_userid: request.session.invalidate() headers = forget(request) return HTTPFound(Settings.get('after_register_redirect')) return {}
def events_view(request): return {'calendar_id': Settings.get('gcal_id'), 'api_key': Settings.get('google_browser_api_key') }
def useredit_ajax_view(request): auth_user = User.bid(request.authenticated_userid) userid = request.matchdict.get('user_id', auth_user.id) if auth_user.is_admin else auth_user.id current_type = request.matchdict.get('type') if not current_type: if 'connection' in request.path: current_type = 'connection' else: current_type = User.gettype(userid) realtype = all_types.get(current_type, current_type) if current_type == 'company': cid = request.matchdict.get('user_id') if 'company' in request.referer: item = DBSession.query(BaseCompany).get(cid) else: item = DBSession.query(BaseCompany).join(User).filter(User.id == cid).first() assert auth_user.is_admin or int(auth_user.id) in [e.id for e in item.employees], \ 'No rights to access this company' elif current_type == 'base': item = User.bid(userid, False) elif current_type == 'tag': item = DBSession.query(Tag).filter(Tag.id == userid).first() if not item and auth_user.is_admin and request.POST: item = Tag(text=request.POST.get('value', '').strip()) DBSession.add(item) elif current_type == 'connection': con_id = request.matchdict.get('con_id') item = DBSession.query(Connection).filter(Connection.id == con_id).first() if con_id else None else: item = DBSession.query(realtype).join(User).filter(User.id == userid).first() if not item and current_type in user_types: item = realtype(user_id=userid) DBSession.add(item) if request.method == 'POST': post_data = request.POST field = post_data.get('name') value = post_data.get('value') select2_company_fields = ['notablecustomers', 'previous_companies', 'startup_wishcustomers', 'areas_of_interest'] select2_founder_fields = ['areas_of_interest'] assert field not in getattr(item, 'only_admin_edit_fields', []) or auth_user.is_admin, 'Only admin can edit that field' try: value = value.strip() except AttributeError: pass if field == 'privatefields_values': value = cPickle.dumps( {k.replace('value[', '').replace(']', ''): v for k, v in post_data.items() if 'value' in k}) elif field == 'acquireddate' or field == 'shutdowndate': value = datetime.strptime(value, '%d %b %Y') if value.strip() else None if field == 'name' and current_type == 'company': if value.strip() != item.name.strip(): admin_mail = Settings.get('admin_mail').split(',')[0] send_mail(admin_mail, 'company_changed', request, {'name': value, 'old_name': item.name}) if field == 'password': # TODO move to model, use assertions if len(value) < 8 or not any(i.isdigit() for i in value): raise AssertionError('Min password length is 8 characters and must contain at least one digit') if not value and not field.endswith('tags') and field not in select2_company_fields: base_checkbox_field = post_data.get('value[]', '').split('_')[0] setattr(item, field, base_checkbox_field) for bool_field in item.boolean_fields: if bool_field.startswith(base_checkbox_field): setattr(item, bool_field, False) other_field = '%s_other' % base_checkbox_field if hasattr(item, other_field): setattr(item, other_field, '') for field in post_data.getall('value[]'): if 'other' in field: fsplit = field.split('_:::_') if len(fsplit) > 1: setattr(item, fsplit[0], fsplit[1]) else: setattr(item, field, True) elif field.endswith('tags') or field in select2_founder_fields: value = handle_if_tags(field, ','.join(post_data.getall('value[]'))) elif field in select2_company_fields: value = handle_if_company_tags(field, ','.join(post_data.getall('value[]'))) elif auth_user.is_admin: value = handle_if_company(field, value, required=False) handle_if_typechange(item, field, value) setattr(item, field, value) return 'OK' return ''
def send_mail(to, etype, request, data=None): add_cc = ["mentoring_request", "mentoring_request_intro"] if data is None: data = {} mi = emails.get(etype, "data").copy() if mi.get("mailer"): mailer = mailer_factory_from_settings(mi.get("mailer"), "") else: mailer = get_mailer(request) if "user" not in data and request.user: data["user"] = request.user if request and request.authenticated_userid and data["user"].id != request.authenticated_userid: data["auth_user"] = request.user for k, v in mi.iteritems(): if callable(v): v = v(data, request) if ".jinja2" in v: v = render(v, data, request) elif isinstance(v, basestring): if "{{" in v and "}}" in v: v = Template(v).render(**data) else: v = v.format(**data) mi[k] = v if "attachments" in data: attachments = data["attachments"] elif "attachments" in mi and mi["attachments"] and mi["attachments"] != "None": with open(os.path.dirname(os.path.dirname(__file__)) + mi["attachments"]) as fo: a_file = fo.read() attachments = [Attachment(os.path.basename(mi["attachments"]), "application/" + mi["attachments"][-3:], a_file)] else: attachments = None if not isinstance(to, list): to = to.split(",") from alchemist.models.settings import Settings send_from = mi.get("from") bcc = [bc for bc in data.get("bcc", mi.get("bcc", "").split(",")) if bc] sender = Settings.get("admin_mail", "*****@*****.**") sender = sender.split(",") main_admin_mail = sender[0].strip() if main_admin_mail: bcc.append(main_admin_mail) if not send_from: send_from = main_admin_mail or "*****@*****.**" cc = mi.get("cc") if mi.get("cc") else [] if "@" not in cc and not isinstance(cc, list): cc = Settings.get(cc, cc).split(",") if not cc and etype in add_cc: cc = [email.strip() for email in Settings.get("cc_emails", "").split(",")] if debug and not set(Settings.get("allowed_outgoing", "").split(",")).issuperset(bcc + cc + to): print "Wanted to send email %s to %s, didn't" % (etype, bcc + cc + to) return None mail = Message(mi["subject"], to, mi["text"], mi["html"], sender=send_from, bcc=bcc, cc=cc) if attachments: mail.attachments = attachments mailer.send(mail)
def get_hmac(self): key = Settings.get('intercom_hmac', 'secret') return hmac.new(str(key), str(self.email or self.id), hashlib.sha256).hexdigest()
def export_users_batch(argv=sys.argv): if len(argv) < 2: usage(argv) config_uri = argv[1] options = parse_vars(argv[2:]) setup_logging(config_uri) settings = get_appsettings(config_uri, options=options) engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) create_attrs = {'name': 'nicename', 'email': 'email', 'contact_email': 'linkedin_email', 'phone': 'phone', #'user_hash': 'get_hmac', 'created_at': 'create_timestamp', 'poc': 'point_of_contact', 'primary_type': 'primary_type', 'total_sent_messages': 'sent', "total_connected_messages": 'connected', "conversion_messages": 'ratio', "Connect_Me-Accepted": 'connect_me_accept', "Connect_Me-Sent": 'connect_me_sent', "Connect_Me-Conv_Rate": 'connect_me_conv', "Request_Meeting-Accepted": 'request_meeting_accept', "Request_Meeting-Sent": 'request_meeting_sent', "Request_Meeting-Conv_Rate": 'request_meeting_conv', "Customer-To-Founder-Accepted": 'company_accept', "Customer-To-Founder-Sent": 'company_sent', "Customer-To-Founder-Conv_Rate": 'company_conv' } not_custom_attrs = ['name', 'email', 'created_at'] with transaction.manager: Intercom.app_id = Settings.get('intercom_id') Intercom.app_api_key = Settings.get('intercom_api_key') users = DBSession.query(User).filter(User.activated == True, User.login_enabled == True).all() print 'Rate limits', Intercom.rate_limit_details print 'Have %s users able to login, starting to update their info in intercom!' % len(users) for user in users: print 'processing user %s' % user.email try: intercom_user = IntercomUser.find(email=user.email) except: print 'created new user for intercom' intercom_user = IntercomUser.create(email=user.email) stats = user.get_connect_stats() changed = False for intercomattr, userattr in create_attrs.iteritems(): val = stats.get(userattr, getattr(user, userattr, None)) if hasattr(val, '__call__'): val = val() if val is None: continue changed = True if intercomattr in not_custom_attrs: setattr(intercom_user, intercomattr, val) else: intercom_user.custom_attributes[intercomattr] = val if user.company: intercom_user.companies = [{'id': user.company.id, 'name': user.company.name}] intercom_user.custom_attributes['class_number'] = user.company.alchemistclass \ if user.company else 'No class' if changed: print 'sending %s info' % user.email intercom_user.save() if Intercom.rate_limit_details.get('remaining', 0) <= 10: break