Пример #1
0
    def load(self, dic):
        # 获取发布微博的用户信息
        uid = 0L
        user = dic.get('user',None)
        if user is None:
            uid = dic.get('uid', dic.get('user_id', None))
            if uid is None:
                raise ValueError('Data Error: Either User information or user id is expected in the status data!')
            else:
                self.uid = uid
        else:
            from profile import UserProfile
            uprofile = UserProfile()
            uprofile.load(user)
            uid = long(uprofile.idstr)
            self.uid = uid

            # 将用户插入到用户表
            self.batches.extend(uprofile.get_batches())

        self.mid = long( dic.get('idstr',dic.get('id')) )

        # 处理转发微博
        r_id = 0
        repost = dic.get('retweeted_status')

        if repost is None:
            pass
        else:
            from weibo import Repost
            # 将转发微博存在repost列族
            retweet = Repost()
            retweet.load(self.uid, self.mid, repost)
            # print retweet
            r_id = retweet.id
            self.batches.extend(retweet.get_batches())

            # 将转发微博对应的原创微博单独存放一份作为原始微博
            if repost.get('deleted', 0) == 0:  # 如果被转发的微博已经被删除,则不保存为原创微博
                original = Status()
                original.load(repost)
                self.batches.extend(original.get_batches())
        self.r_id = long(r_id)

        # 处理其他字段信息
        for attr in Status.attrs:
            v = dic.get(attr)
            if attr == 'key':
                v = dic.get('id')
            if v is None:
                if attr in ['reposts_count', 'comments_count', 'attitudes_count']:
                    v = 0
                else:
                    continue

            self.setattr(attr,v)

        ustatus = UserStatuses()
        ustatus.load(self, self.uid)
        self.batches.extend(ustatus.get_batches())
Пример #2
0
def render_autopass_puzzle(puzzle):
    # get passphrase that was submitted with this request, if any:
    submitted = request.args.get('pass')
    # get current user's passphrase:
    profile = UserProfile.get_by_user(request.remote_addr)
    # see if they submitted the correct one:
    if submitted and (submitted == profile.current_passphrase):
        profile.solved_puzzles.append('autopass/' + puzzle)
        profile.put()
        value = 'correct! '
        value += progress('autopass/' + puzzle)
        return value

    # fallthrough logic - incorrect or no passphrase submitted:

    # TODO: add extra output on pass submitted, but incorrect?
    # (but then it'd be outside of the manual HTML structure)

    # generate a new passphrase:
    passphrase = 'default'
    with app.open_resource('data/passphrases.json') as f:
        passphrases = json.load(f)
        passphrase = random.choice(passphrases)

    # store it in user's profile:
    profile.current_passphrase = passphrase
    profile.put()

    return render_template('autopass/' + puzzle, passphrase=passphrase)
Пример #3
0
 def get_username_from_system_user_id(self, envid, system_user_id):
     # pylint: disable=invalid-name
     profile = UserProfile.get_by_system_user_id(envid, system_user_id)
     if profile:
         return profile.display_name()
     else:
         # FIXME: probably not correct.
         return UNDEFINED
Пример #4
0
def progress(curr):
    profile = UserProfile.get_by_user(request.remote_addr)
    nextp = nextPuzzle(curr)
    if nextp:
        profile.current_puzzle = nextp  # this is probably fine.
        profile.put()
        return '<a href="/' + nextp + '">Next puzzle!</a>'
    else:
        # no next puzzle
        return 'All done!'
Пример #5
0
    def get_batches(self):
        #用于存储需要更新的内容,可能涉及多个表、多个列族
        batches = []

        #根据关系用户,将关系用户的Profile插入到表中
        for uid, user in self.users.iteritems():
            uprofile = UserProfile()
            uprofile.load(user)
            batches_uprofile = uprofile.get_batches()
            batches.extend(batches_uprofile)

        #根据关系情况,把用户的id插入到_user:relation列族中
        mutations = []
        for uid, relation in self.uids.iteritems():
            qualifier = struct.pack('<q', uid)

            user = self.users[uid]
            gender = user['gender']
            vt = user['verified_type']
            vt = verified_type_map.get(vt, vt)
            v = vt << 3
            v |= 4L if gender == 'm' else 0L
            v |= relation

            v <<= 32
            v |= util.now2epoch()

            v = struct.pack('>q', v)
            m = Mutation(column="%s:%s" % (Relation.column_family, qualifier),
                         value=v)
            mutations.append(m)
        key = struct.pack('<q', self.self_uid)

        u_relation = {
            'tableName': Relation.tableName,
            'rowBatches': BatchMutation(row=key, mutations=mutations)
        }
        batches.append(u_relation)

        return batches
Пример #6
0
    def _eventgen(self, key, agent, entry, body=None):
        if body is None:
            body = {}
        body = dict(body.items() +\
                        agent.todict().items() +\
                        entry.todict().items())

        body['http_status'] = responses[entry.status]

        system_user_id = entry.system_user_id
        if system_user_id != -1:
            profile = UserProfile.get_by_system_user_id(
                entry.envid, entry.system_user_id)
            if profile:
                # This is the browser/viewer user, and not the
                # workbook publisher/owner.
                body['username'] = profile.display_name()

        # An event in the event_control table expects these to exist,
        # but if workbook archiving is off, or the workbook isn't
        # found they will not be set.
        body['owner'] = None
        body['workbook'] = None

        body['userid'] = None  # default

        if 'repository_url' in body:
            self._translate_workbook(body, entry)

        if 'http_referer' in body:
            body['http_referer'] = unquote(body['http_referer']).decode('utf8')

        if 'http_request_uri' in body:
            # Remove query string from the http_request_uri.
            urip = urlparse(body['http_request_uri'])
            http_request_uri = urip.scheme + "://" + urip.netloc + urip.path

            http_request_uri = unquote(http_request_uri)
            body['http_request_uri'] = http_request_uri.decode('utf8')

        userid = body['userid']

        completed_at = utc2local(entry.completed_at)
        self.server.event_control.gen(key,
                                      body,
                                      userid=userid,
                                      timestamp=completed_at)
Пример #7
0
    def _eventit(self, agent, data):
        """Send a read-only password event failed/okay event if
           the user has done setup with a chance to
           configure one and appropriate."""

        # user '0', likely 'palette'
        entry = UserProfile.get(self.server.environment.envid, 0)
        # Potentially send an event only after the user has
        # finished with the "Setup" page (the passowrd will then be
        # there).

        if not entry.hashed_password:
            return

        notification = self.server.notifications.get("dbreadonly")

        if success(data):
            if notification.color == 'red':
                adata = agent.todict()
                self.server.event_control.gen(
                    EventControl.READONLY_DBPASSWORD_OKAY, adata)
                notification.modification_time = func.now()
                notification.color = 'green'
                notification.description = None
                meta.Session.commit()
        else:
            # Failed
            if notification.color != 'red':
                if data['error'].find(
                    "A password is required for this connection.") != -1 or \
                    data['error'].find(agent.odbc.READONLY_ERROR_TEXT) \
                                                                    != -1 or \
                    data['error'].find("password authentication failed") != -1:

                    adata = agent.todict()
                    self.server.event_control.gen(
                        EventControl.READONLY_DBPASSWORD_FAILED, adata)
                    notification.modification_time = func.now()
                    notification.color = 'red'
                    notification.description = None
                    meta.Session.commit()
            return
Пример #8
0
    def _eventgen(self, key, data, entry):
        """Fill in information into the data dictionary and send the event."""
        # Placeholder to be set by the next steps.
        entry.system_user_id = -1

        item_entry = self._add_info(entry)

        if key == EventControl.EXTRACT_OK:
            if item_entry:
                self.server.extract_archive.add(item_entry, entry)
            else:
                logger.info("extract OK: Can't archive workbook/datasource "
                            "row  - not found.")

        data = dict(data.items() + entry.todict().items())

        if entry.completed_at is not None and entry.started_at is not None:
            duration = timedelta_total_seconds(entry.completed_at,
                                               entry.started_at)
            data['duration'] = duration
            data['duration_hms'] = to_hhmmss(duration)
            timestamp = utc2local(entry.completed_at)
        else:
            timestamp = None

        envid = self.server.environment.envid
        profile = UserProfile.get_by_system_user_id(envid,
                                                    data['system_user_id'])
        if profile:
            data['username'] = profile.display_name()
            userid = profile.userid
        else:
            data['username'] = "******"
            userid = None

        self.server.event_control.gen(key,
                                      data,
                                      userid=userid,
                                      site_id=data['site_id'],
                                      timestamp=timestamp)
Пример #9
0
    def _translate_workbook(self, body, entry):
        envid = self.server.environment.envid

        url = body['repository_url']
        try:
            workbook = WorkbookEntry.get_by_url(envid,
                                                url,
                                                entry.site_id,
                                                default=None)
        except MultipleResultsFound:
            logger.warning("Multiple rows found for url '%s', site_id: '%s'",
                           url, entry.site_id)
            body['workbook'] = 'Unknown: Duplicate repository url'
            body['owner'] = 'Unknown: Duplicate repository url'
            return

        if not workbook:
            logger.warning("repository_url '%s' Not Found.", url)
            return
        body['workbook'] = workbook.name

        # Send this userid on event generation (workbook owner, not viewer).
        user = UserProfile.get_by_system_user_id(envid,
                                                 workbook.system_user_id)
        if user:
            body['userid'] = user.userid
            body['owner'] = user.display_name()
        else:
            logger.warning("system user '%d' Not Found.",
                           workbook.system_user_id)
        body['project'] = workbook.project

        if workbook.site:
            body['site'] = workbook.site
        else:
            if entry.site_id:
                site = Site.get(entry.envid, entry.site_id)
                if site:
                    body['site'] = site.name
Пример #10
0
    def sendevent(self, key, system_user_id, error, data):
        """Send the event."""

        if 'embedded' in data:
            del data['embedded']
        if error:
            logger.error(error)
            data['error'] = error

        profile = UserProfile.get_by_system_user_id(
            self.server.environment.envid, system_user_id)

        if profile:
            username = profile.display_name()
            userid = profile.userid
        else:
            username = None
            userid = None

        if username and not 'owner' in data:
            data['owner'] = username

        return self.server.event_control.gen(key, data, userid=userid)
Пример #11
0
    def send(self, event_entry, data, recipient=None, eventid=None):
        """Send an alert.
            Arguments:
                key:    The key to look up.
                data:   A Dictionary with the event information.
        """
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-return-statements

        subject = event_entry.email_subject
        if subject == None:
            subject = event_entry.subject

        if subject.find("%") != -1:
            # Use the data dict for template substitution.
            try:
                subject = subject % data
            except (ValueError, KeyError) as ex:
                subject = "Email Template subject conversion failure: " + \
                    str(ex) + \
                    "subject: " + subject + \
                    ", data: " + str(data)

        message = event_entry.email_message
        if message:
            try:
                mako_template = Template(message)
                message = mako_template.render(**data)
            except StandardError:
                message = "Email mako template message conversion failure: " + \
                    exceptions.text_error_template().render() + \
                    "\ntemplate: " + message + \
                        "\ndata: " + str(data)
        else:
            message = self.make_default_message(event_entry, subject, data)

        if not message:
            # message is empty, set it to be the subject
            message = subject

        if recipient:
            # Force to only one test recipient.
            # It is sent even if alerts are disabled.
            to_emails = [recipient]
        else:
            if not self.system[SystemKeys.ALERTS_ENABLED]:
                logger.info("Alerts disabled.  Not sending: Subject: %s, %s",
                            subject, message)
                return

            to_emails = []

            if event_entry.publisher_visibility:
                to_emails = self.publisher_email(data)
            if event_entry.admin_visibility:
                to_emails += self.admin_emails(event_entry)

        # Remove any duplicates
        to_emails = list(set(to_emails))

        bcc = None
        if self.system[SystemKeys.ALERTS_ADMIN_ENABLED] and not recipient:
            # Get the diagnostics email and bcc it there if it exists.
            entry = UserProfile.get(self.envid, 0)
            if entry and entry.email != None and entry.email != "":
                bcc = [entry.email]

        if not to_emails and not bcc:
            logger.debug(
                "No admin users exist with enabled email addresses. "
                "Not sending: Subject: %s, Message: %s", subject, message)
            return

        # Send only PHONE-HOME related events if their palette license
        # has expired.
        if event_entry.key not in [
                EventControl.PHONE_HOME_FAILED, EventControl.PHONE_HOME_OK,
                EventControl.EMAIL_TEST
        ]:
            entry = Domain.getone()
            if entry.expiration_time and \
                            datetime.utcnow() > entry.expiration_time:
                logger.debug(
                    "License expired. " +
                    "Not sending: Subject: %s, Message: %s", subject, message)
                return

            if entry.contact_time:
                silence_time = (datetime.utcnow() - \
                                        entry.contact_time).total_seconds()
                max_silence_time = self.system[SystemKeys.MAX_SILENCE_TIME]
                if silence_time > max_silence_time and max_silence_time != -1:
                    logger.debug(
                        "Phonehome contact time is %d > %d. " +
                        "Not sending: Subject: %s, Message: %s", silence_time,
                        max_silence_time, subject, message)
                    return

        if self.email_limit_manager.email_limit_reached(event_entry, eventid):
            return

        sendit = True
        #        print '\n------------event key is', event_entry.key
        if self.system[SystemKeys.EMAIL_MUTE_RECONNECT_SECONDS]:
            # Potentially mute the connect or reconnect emails.
            if event_entry.key == EventControl.AGENT_DISCONNECT:
                self._mute_dis_check(data, to_emails, bcc, subject, message)
                # If the event is emailed, it is done there,
                # after a delay
                return

            elif event_entry.key in [
                    EventControl.AGENT_COMMUNICATION,
                    EventControl.INIT_STATE_STARTED,
                    EventControl.INIT_STATE_STOPPED,
                    EventControl.INIT_STATE_DEGRADED
            ]:
                sendit = self._mute_reconn_check(data)

        if sendit:
            self._do_send(to_emails, bcc, subject, message)
Пример #12
0
 def verify(self, name, password):
     return UserProfile.verify(self.server.environment.envid, name,
                               password)
Пример #13
0
    def load(self, agent, check_odbc_state=True):
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        envid = self.server.environment.envid

        if check_odbc_state and not self.server.odbc_ok():
            return {"error": "Cannot run command while in state: %s" % \
                        self.server.state_manager.get_state()}

        stmt = \
            'SELECT system_users.name, system_users.email, ' +\
            ' system_users.hashed_password, system_users.salt, ' +\
            ' system_users.friendly_name, system_users.admin_level, ' +\
            ' system_users.created_at, system_users.id ' +\
            'FROM system_users'

        excludes = ['guest', '_system']

        data = agent.odbc.execute(stmt)

        # Send tableau readonly password-related events if appropriate.
        self._eventit(agent, data)

        if failed(data):
            return data

        session = meta.Session()

        names = ['palette']
        cache = self.load_users(agent)

        system_key = SystemKeys.ALERTS_NEW_USER_ENABLED
        alerts_new_user_enabled = self.system[system_key]
        if alerts_new_user_enabled == 'yes':
            default_email_level = 1
        else:
            default_email_level = 0

        user_count = UserProfile.user_count(envid)
        if user_count <= 1:
            first_load = True
        else:
            first_load = False

        for row in data['']:
            name = row[0]
            if name.lower() in excludes:
                continue

            sysid = row[7]
            names.append(name)

            entry = UserProfile.get_by_name(envid, name)
            if not entry:
                entry = UserProfile(envid=envid, name=name)
                entry.email_level = default_email_level
                session.add(entry)

            entry.email = row[1]
            entry.hashed_password = row[2]
            entry.salt = row[3]
            entry.friendly_name = row[4]
            entry.system_admin_level = row[5]
            entry.system_created_at = row[6]
            entry.system_user_id = sysid

            if sysid in cache:
                obj = cache[sysid]
                entry.login_at = obj.login_at
                entry.user_admin_level = obj.admin_level
                entry.licensing_role_id = obj.licensing_role_id
                entry.publisher = obj.publisher

            # On first user table import, Tableau Server Administrators
            # are set to Palette Super Admins.
            if first_load and entry.system_admin_level == 10:
                entry.roleid = Role.SUPER_ADMIN

        session.commit()

        # deleted entries no longer found in Tableau are marked inactive.
        session.query(UserProfile).\
            filter(not_(UserProfile.name.in_(names))).\
            update({'active': False}, synchronize_session='fetch')

        timestamp = datetime.now().strftime(DATEFMT)
        self.system.save(SystemKeys.AUTH_TIMESTAMP, timestamp)

        d = {u'status': 'OK', u'count': len(data[''])}
        logger.debug("auth load returning: %s", str(d))
        return d
Пример #14
0
    def load(self, dic):
        # 获取发布微博的用户信息
        uid = 0L
        user = dic.get('user', None)
        if user is None:
            uid = dic.get('uid', dic.get('user_id', None))
            if uid is None:
                raise ValueError(
                    'Data Error: Either User information or user id is expected in the status data!'
                )
            else:
                self.uid = uid
        else:
            from profile import UserProfile
            uprofile = UserProfile()
            uprofile.load(user)
            uid = long(uprofile.idstr)
            self.uid = uid

            # 将用户插入到用户表
            self.batches.extend(uprofile.get_batches())

        self.mid = long(dic.get('idstr', dic.get('id')))

        # 处理转发微博
        r_id = 0
        repost = dic.get('retweeted_status')

        if repost is None:
            pass
        else:
            from weibo import Repost
            # 将转发微博存在repost列族
            retweet = Repost()
            retweet.load(self.uid, self.mid, repost)
            # print retweet
            r_id = retweet.id
            self.batches.extend(retweet.get_batches())

            # 将转发微博对应的原创微博单独存放一份作为原始微博
            if repost.get('deleted', 0) == 0:  # 如果被转发的微博已经被删除,则不保存为原创微博
                original = Status()
                original.load(repost)
                self.batches.extend(original.get_batches())
        self.r_id = long(r_id)

        # 处理其他字段信息
        for attr in Status.attrs:
            v = dic.get(attr)
            if attr == 'key':
                v = dic.get('id')
            if v is None:
                if attr in [
                        'reposts_count', 'comments_count', 'attitudes_count'
                ]:
                    v = 0
                else:
                    continue

            self.setattr(attr, v)

        ustatus = UserStatuses()
        ustatus.load(self, self.uid)
        self.batches.extend(ustatus.get_batches())
Пример #15
0
def nextStep():
    print request.remote_addr
    profile = UserProfile.get_by_user(request.remote_addr)
    print profile
    return redirect(profile.current_puzzle)
Пример #16
0
    def gen(self, key, data=None, userid=None, site_id=None, timestamp=None):
        # pylint: disable=too-many-arguments
        # pylint: disable=too-many-locals
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-branches
        """Generate an event.
            Arguments:
                key:    The key to look up.

                data:   A Dictionary with all of the event information.
                        Recognized keys:
                            - From http response:
                                stdout
                                stderr
                                xid
                                pid
                                exit-status
                                run-status
                                timestamp
                            - Sometimes added:
                                error
                                info
                            - Available from AgentConnection:
                                displayname
                                agent_type
                                uuid
                                auth, which has:
                                    hostname
                                    ip-address
                                    version
                                    listen-port
                                    install-dir
        """

        if data == None:
            data = {}

        if 'enabled' in data and not data['enabled']:
            logger.debug("Agent is disabled so no event will be " + \
                         "generated.  key: %s, data: %s", key, data)
            return

        event_entry = self.get_event_control_entry(key)
        if event_entry:
            subject = event_entry.subject
            event_description = event_entry.event_description
        else:
            logger.error("No such event key: %s. data: %s\n", key, str(data))
            return

        # add all system table entries to the data dictionary.
        data = dict(data.items() + \
                    self.system.todict(include_defaults=True).items())

        logger.debug(key + " DATA: " + str(data))

        if 'exit-status' in data:
            data['exit_status'] = data['exit-status']
            del data['exit-status']

        # FIXME: remove when browser-aware timezone support is available.
        if timestamp is None:
            timestamp = datetime.datetime.now(tz=tz.tzlocal())
            logger.debug(key + " timestamp : " + timestamp.strftime(DATEFMT))
        data['timestamp'] = timestamp.strftime(DATEFMT)

        # The userid for other events is the Palette "userid".
        profile = None
        if not 'username' in data and userid != None:
            profile = UserProfile.get(self.envid, userid)

        if not profile is None:
            data['username'] = profile.display_name()
            data['userid'] = profile.userid
            if profile.email:
                data['email'] = profile.email

        if userid:
            # userid passed to us has higher precedence than any
            # lookup we did, above.
            data['userid'] = userid

        if not 'username' in data:
            data['username'] = mako.runtime.UNDEFINED

        data['event_type'] = event_entry.event_type
        data['event_type_label'] = event_entry.event_type_label
        data['event_label'] = event_entry.event_label
        data['event_label_desc'] = event_entry.event_label_desc
        data['admin_visibility'] = event_entry.admin_visibility
        data['publisher_visiblity'] = event_entry.publisher_visibility

        # set server-url(s)
        data['server_url'] = self.system[SystemKeys.SERVER_URL]

        url = self.server.public_url()
        if url:
            data['tableau_server_url'] = url

        if not 'environment' in data:
            data['environment'] = self.server.environment.name

        if 'site_id' in data and 'site' not in data:
            site = Site.get_name_by_id(self.envid, data['site_id'])
            if not site is None:
                data['site'] = site
        if 'project_id' in data and 'project' not in data:
            project = Project.get_name_by_id(self.envid, data['project_id'])
            if not project is None:
                data['project'] = project

        # Create the row to get the eventid before doing subject/description
        # substitution.
        session = meta.DBSession()
        entry = EventEntry(complete=False, key='incomplete')
        # set the timestamp here in case it has tzinfo.
        entry.timestamp = timestamp
        session.add(entry)
        session.commit()

        data['eventid'] = entry.eventid

        # Use the data dict for template substitution.
        try:
            subject = subject % data
        except (ValueError, KeyError) as ex:
            subject = "Template subject conversion failure: " + str(ex) + \
                      "subject: " + subject + \
                      ", data: " + str(data)

        if event_description:
            try:
                mako_template = Template(event_description,
                                         default_filters=['h'])
                event_description = mako_template.render(**data)
            except MakoException:
                event_description = \
                    "Mako template message conversion failure: " + \
                        exceptions.text_error_template().render() + \
                            "\ntemplate: " + event_description + \
                            "\ndata: " + str(data)
            except TypeError as ex:
                event_description = \
                    "Mako template message conversion failure: " + \
                    str(ex) + \
                        "\ntemplate: " + event_description + \
                        "\ndata: " + str(data)
        else:
            event_description = self.make_default_description(data)

        event_description = re.sub("(\n|\r\n){3,}", "\n\n", event_description)
        if not event_description.endswith("\n"):
            event_description = event_description + "\n"

        if self.server.event_debug:
            event_description = event_description + "--------\n" + str(data)

        # FIXME: remove when browser-aware timezone support is available.
        if timestamp.tzinfo is None:
            # if not timezone is specified, assume UTC.
            summary = utc2local(timestamp).strftime(DATEFMT)
        else:
            summary = timestamp.strftime(DATEFMT)

        # Log the event to the database
        entry.complete = True
        entry.key = key
        entry.envid = self.envid
        entry.title = subject
        entry.description = event_description
        entry.level = event_entry.level
        entry.icon = event_entry.icon
        entry.color = event_entry.color
        entry.event_type = event_entry.event_type
        entry.summary = summary
        entry.userid = userid
        entry.site_id = site_id
        #entry.timestamp = timestamp

        session.merge(entry)
        session.commit()

        if not event_entry.send_email:
            return

        try:
            self.alert_email.send(event_entry, data, eventid=entry.eventid)
        except StandardError:
            exc_traceback = sys.exc_info()[2]
            tback = ''.join(traceback.format_tb(exc_traceback))
            report = "Error: %s.  Traceback: %s" % (sys.exc_info()[1], tback)

            logger.error(
                "alert_email: Failed for event '%s', '"
                "data '%s'.  Will not send email. %s", event_entry.key,
                str(data), report)