Beispiel #1
0
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']
    }
Beispiel #2
0
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)
Beispiel #3
0
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}
Beispiel #4
0
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)
Beispiel #5
0
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
Beispiel #6
0
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}
Beispiel #7
0
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))
Beispiel #8
0
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
Beispiel #9
0
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')
Beispiel #10
0
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)
Beispiel #11
0
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))
Beispiel #12
0
def logout_view(request):
    if request.authenticated_userid:
        request.session.invalidate()
        headers = forget(request)
        return HTTPFound(Settings.get('after_register_redirect'))
    return {}
Beispiel #13
0
def events_view(request):
    return {'calendar_id': Settings.get('gcal_id'),
            'api_key': Settings.get('google_browser_api_key')
            }
Beispiel #14
0
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 ''
Beispiel #15
0
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)
Beispiel #16
0
 def get_hmac(self):
     key = Settings.get('intercom_hmac', 'secret')
     return hmac.new(str(key), str(self.email or self.id), hashlib.sha256).hexdigest()
Beispiel #17
0
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