Exemplo n.º 1
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True, enable=[
         default_workflow.ConfigurableTicketWorkflow,
         DefaultPermissionPolicy, DefaultPermissionStore,
         BatchModifyModule, api.TicketSystem, web_ui.TicketModule
     ])
     self.env.config.set('trac', 'permission_policies',
                         'DefaultPermissionPolicy')
     self.env.config.set('ticket-custom', 'text1', 'text')
     self.env.config.set('ticket-custom', 'text1.max_size', 5)
     self.env.config.set('ticket-custom', 'time1', 'time')
     self.env.config.set('ticket-custom', 'time1.format', 'date')
     self.env.config.set('ticket-workflow',
                         'acknowledge', '* -> acknowledged')
     ps = PermissionSystem(self.env)
     ps.grant_permission('has_ta_&_bm', 'TICKET_ADMIN')
     ps.grant_permission('has_bm', 'TICKET_BATCH_MODIFY')
     ps.grant_permission('has_ta_&_bm', 'TICKET_BATCH_MODIFY')
     session = DetachedSession(self.env, 'has_ta_&_bm')
     session.set('query_href', '')
     session.save()
     session = DetachedSession(self.env, 'has_bm')
     session.set('query_href', '')
     session.save()
     self._insert_ticket('Ticket 1', reporter='user1',
                         component='component1', description='the desc',
                         keywords='foo one', status='new')
     self._insert_ticket('Ticket 2', reporter='user1',
                         component='component2', description='the desc',
                         keywords='baz two', status='new')
Exemplo n.º 2
0
 def test_find_session_by_attr(self, env, helper):
     ds = DetachedSession(env, 'foo')
     ds['bar'] = 'baz'
     ds.save()
     ds = DetachedSession(env, 'wrong')
     ds['bar'] = 'not baz'
     ds.save()
     assert helper.find_session_by_attr('bar', 'baz') == ['foo']
Exemplo n.º 3
0
    def create_session(self, authname_base, attributes):
        """Create a new authenticated session.

        (In trac, authenticated sessions are, essentially “user accounts”,
        so this creates a new account or “login” on the trac.)

        If possible, the session is created with an ``sid`` of
        ``authname_base``.  If a session already exists with that
        ``sid``, then a suffix is added to make the ``sid`` unique.

        The attributes of the new session are initialized from the
        ``attributes`` argument, if any.

        The ``sid`` of the new session is returned.

        """
        if not attributes:
            raise ValueError("Attributes required for new session")

        for suffix in self.uniquifier_suffixes():
            authname = authname_base + suffix
            if self.permission_exists_for(authname):
                continue
            ds = DetachedSession(self.env, authname)
            # At least in 0.12.2, this means no session exists.
            is_new = ds.last_visit == 0 and len(ds) == 0
            if is_new:
                break
        for key, value in attributes.items():
            ds[key] = value or ''
        ds.save()
        return authname
Exemplo n.º 4
0
 def _add_session(self, sid, values=None, **attrs):
     session = DetachedSession(self.env, sid)
     if values is not None:
         attrs.update(values)
     for name, value in attrs.iteritems():
         session[name] = value
     session.save()
Exemplo n.º 5
0
    def getSession(self, queueid):
        cursor = self.env.get_db_cnx().cursor()

        cursor.execute("SELECT status, owner FROM buildqueue WHERE id = %s", (queueid,))
        if cursor.rowcount != 1:
            return False

        row = cursor.fetchone()

        if row[0] != 90:
            return False

        if find(row[1], '@') != -1:
            return DetachedSession(self.env, "qatbot")

        return DetachedSession(self.env, row[1])
Exemplo n.º 6
0
    def _create_request(self, authname='anonymous', **kwargs):
        kw = {
            'perm': PermissionCache(self.env, authname),
            'args': {},
            'callbacks': {},
            'path_info': '',
            'form_token': None,
            'href': self.env.href,
            'abs_href': self.env.abs_href,
            'tz': utc,
            'locale': None,
            'lc_time': None,
            'session': DetachedSession(self.env, authname),
            'authname': authname,
            'chrome': {
                'notices': [],
                'warnings': []
            },
            'method': None,
            'get_header': lambda v: None,
            'is_xhr': False
        }
        kw.update(kwargs)

        def send(self, content, content_type='text/html', status=200):
            raise RequestDone

        return Mock(send=send, **kw)
Exemplo n.º 7
0
    def _create_request(self, authname='anonymous', **kwargs):
        kw = {
            'path_info': '/',
            'perm': MockPerm(),
            'args': _RequestArgs(),
            'href': self.env.href,
            'abs_href': self.env.abs_href,
            'tz': utc,
            'locale': None,
            'lc_time': locale_en,
            'session': DetachedSession(self.env, authname),
            'authname': authname,
            'chrome': {
                'notices': [],
                'warnings': []
            },
            'method': None,
            'get_header': lambda v: None,
            'is_xhr': False,
            'form_token': None
        }
        if 'args' in kwargs:
            kw['args'].update(kwargs.pop('args'))
        kw.update(kwargs)

        def redirect(url, permanent=False):
            raise RequestDone

        return Mock(add_redirect_listener=lambda x: [].append(x),
                    redirect=redirect,
                    **kw)
Exemplo n.º 8
0
Arquivo: session.py Projeto: t2y/trac
    def test_session_set(self):
        """Verify that setting a variable in a session to the default value
        removes it from the session.
        """
        with self.env.db_transaction as db:
            db("INSERT INTO session VALUES ('john', 1, 0)")
            db("INSERT INTO session_attribute VALUES ('john', 1, 'foo', 'bar')"
               )

        session = DetachedSession(self.env, 'john')
        self.assertEqual('bar', session['foo'])

        # Setting the variable to the default value removes the variable
        with self.env.db_transaction as db:
            session.set('foo', 'default', 'default')
            session.save()
        self.assertEqual(
            0,
            self.env.db_query("""
            SELECT COUNT(*) FROM session_attribute
            WHERE sid='john' AND name='foo'
            """)[0][0])

        # Setting the variable to a value different from the default sets it
        with self.env.db_transaction as db:
            session.set('foo', 'something', 'default')
            session.save()
        self.assertEqual(
            'something',
            self.env.db_query("""
            SELECT value FROM session_attribute
            WHERE sid='john' AND name='foo'
            """)[0][0])
Exemplo n.º 9
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True, enable=[
         default_workflow.ConfigurableTicketWorkflow,
         DefaultPermissionPolicy, DefaultPermissionStore,
         BatchModifyModule, api.TicketSystem, web_ui.TicketModule
     ])
     self.env.config.set('trac', 'permission_policies',
                         'DefaultPermissionPolicy')
     ps = PermissionSystem(self.env)
     ps.grant_permission('has_ta_&_bm', 'TICKET_ADMIN')
     ps.grant_permission('has_bm', 'TICKET_BATCH_MODIFY')
     ps.grant_permission('has_ta_&_bm', 'TICKET_BATCH_MODIFY')
     session = DetachedSession(self.env, 'has_ta_&_bm')
     session.set('query_href', '')
     session.save()
     session = DetachedSession(self.env, 'has_bm')
     session.set('query_href', '')
     session.save()
Exemplo n.º 10
0
    def test_session_set_email(self):
        """Setting session email invalidates known_users cache."""
        session = DetachedSession(self.env, 'user')
        session['email'] = '*****@*****.**'

        self.assertEqual([], list(self.env.get_known_users()))
        session.save()
        email = None
        for sid, name, email in self.env.get_known_users():
            if sid == 'user':
                break
        self.assertEqual(session['email'], email)
Exemplo n.º 11
0
    def test_session_set_name(self):
        """Setting session name invalidates known_users cache."""
        session = DetachedSession(self.env, 'user')
        session['name'] = 'The User'

        self.assertEqual([], list(self.env.get_known_users()))
        session.save()
        name = None
        for sid, name, email in self.env.get_known_users():
            if sid == 'user':
                break
        self.assertEqual(session['name'], name)
Exemplo n.º 12
0
    def test_create_new_session(self):
        """Setting attribute on a new session invalidates known_users cache."""
        sid = 'user'
        session = DetachedSession(self.env, sid)
        session.authenticated = True

        self.assertEqual([], list(self.env.get_known_users()))
        session.save()
        known_users = list(self.env.get_known_users())
        self.assertEqual(1, len(known_users))
        self.assertEqual(sid, known_users[0][0])
        self.assertIsNone(known_users[0][1])
        self.assertIsNone(known_users[0][2])
Exemplo n.º 13
0
 def test_find_session_by_identity_url(self, env, userdb):
     bare_id_token = {'iss': 'https://example.net', 'sub': '42'}
     id_token = {
         'iss': 'https://example.net',
         'sub': '42',
         'openid_id': 'https://example.org/foo'
     }
     ds = DetachedSession(env, 'bar')
     ds['openid_session_identity_url_data'] = 'https://example.org/foo'
     ds.save()
     assert userdb.find_session(bare_id_token) is None
     assert userdb.find_session(id_token) == 'bar'
     assert userdb.find_session(bare_id_token) == 'bar'
Exemplo n.º 14
0
    def test_session_set_email(self):
        """Setting session email invalidates known_users cache."""
        sid = 'user'
        email = '*****@*****.**'
        session = DetachedSession(self.env, sid)
        session['email'] = email

        self.assertEqual([], list(self.env.get_known_users()))
        session.save()
        known_users = list(self.env.get_known_users())
        self.assertEqual(1, len(known_users))
        self.assertEqual(sid, known_users[0][0])
        self.assertIsNone(known_users[0][1])
        self.assertEqual(email, known_users[0][2])
Exemplo n.º 15
0
    def test_session_set_name(self):
        """Setting session name invalidates known_users cache."""
        sid = 'user'
        name = 'The User'
        session = DetachedSession(self.env, sid)
        session['name'] = name

        self.assertEqual([], list(self.env.get_known_users()))
        session.save()
        known_users = list(self.env.get_known_users())
        self.assertEqual(1, len(known_users))
        self.assertEqual(sid, known_users[0][0])
        self.assertEqual(name, known_users[0][1])
        self.assertIsNone(known_users[0][2])
Exemplo n.º 16
0
    def test_create_new_anonymous_session(self):
        """Setting attribute on a new anonymous session doesn't invalidate
        known_users cache."""
        sid = 'anonymous'
        session = DetachedSession(self.env, sid)
        session.authenticated = False

        self.assertEqual([], list(self.env.get_known_users()))
        # insert a session record without invalidating cache
        self.env.insert_users([('user', 'Name' '*****@*****.**', 1)])
        session.save()
        self.assertEqual([], list(self.env.get_known_users()))

        self.env.invalidate_known_users_cache()
        self.assertEqual(1, len(list(self.env.get_known_users())))
Exemplo n.º 17
0
    def test_delete_detached_session_var(self):
        """
        Verify that removing a variable in a session not associated with a
        request deletes the variable from the database.
        """
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO session VALUES ('john', 1, 0)")
        cursor.execute("INSERT INTO session_attribute VALUES "
                       "('john', 1, 'foo', 'bar')")

        session = DetachedSession(self.env, 'john')
        self.assertEqual('bar', session['foo'])
        del session['foo']
        session.save()
        cursor.execute("SELECT COUNT(*) FROM session_attribute "
                       "WHERE sid='john' AND name='foo'")
        self.assertEqual(0, cursor.fetchone()[0])
Exemplo n.º 18
0
    def test_modify_detached_session(self):
        """
        Verify that modifying a variable in a session not associated with a
        request updates the database accordingly.
        """
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO session VALUES ('john', 1, 0)")
        cursor.execute("INSERT INTO session_attribute VALUES "
                       "('john', 1, 'foo', 'bar')")

        session = DetachedSession(self.env, 'john')
        self.assertEqual('bar', session['foo'])
        session['foo'] = 'baz'
        session.save()
        cursor.execute("SELECT value FROM session_attribute "
                       "WHERE sid='john' AND name='foo'")
        self.assertEqual('baz', cursor.fetchone()[0])
Exemplo n.º 19
0
    def test_modify_detached_session(self):
        """
        Verify that modifying a variable in a session not associated with a
        request updates the database accordingly.
        """
        with self.env.db_transaction as db:
            db("INSERT INTO session VALUES ('john', 1, 0)")
            db("INSERT INTO session_attribute VALUES ('john', 1, 'foo', 'bar')")

            session = DetachedSession(self.env, 'john')
            self.assertEqual('bar', session['foo'])
            session['foo'] = 'baz'
            session.save()

        self.assertEqual('baz', self.env.db_query("""
            SELECT value FROM session_attribute WHERE sid='john' AND name='foo'
            """)[0][0])
Exemplo n.º 20
0
    def test_delete_detached_session_var(self):
        """
        Verify that removing a variable in a session not associated with a
        request deletes the variable from the database.
        """
        with self.env.db_transaction as db:
            db("INSERT INTO session VALUES ('john', 1, 0)")
            db("INSERT INTO session_attribute VALUES ('john', 1, 'foo', 'bar')")

            session = DetachedSession(self.env, 'john')
            self.assertEqual('bar', session['foo'])
            del session['foo']
            session.save()
         
        self.assertEqual(0, self.env.db_query("""
            SELECT COUNT(*) FROM session_attribute
            WHERE sid='john' AND name='foo'
            """)[0][0])
Exemplo n.º 21
0
 def test_get_main_page(self):
     req = Mock(path_info='/tags',
                args={},
                authname='reader',
                perm=self.reader,
                href=self.href,
                method='GET',
                chrome=dict(static_hash='hashme!'),
                session=DetachedSession(self.env, 'reader'),
                locale='',
                tz='')
     template, data, content_type = self.tag_rh.process_request(req)
     self.assertEquals('tag_view.html', template)
     self.assertEquals(None, content_type)
     self.assertEquals([
         'checked_realms', 'mincount', 'page_title', 'tag_body',
         'tag_query', 'tag_realms'
     ], sorted(data.keys()))
Exemplo n.º 22
0
 def associate_session(self, authname, iss, sub):
     ds = DetachedSession(self.env, authname)
     ds[self.SUBJECT_SKEY] = self.subject_uri(iss, sub)
     ds.save()
Exemplo n.º 23
0
    def _do_process(self, req):
        """Handle the redirect from the OpenID server.
        """
        db = self.env.get_db_cnx()
        oidconsumer, oidsession = self._get_consumer(req, db)

        # Ask the library to check the response that the server sent
        # us.  Status is a code indicating the response type. info is
        # either None or a string containing more information about
        # the return type.
        info = oidconsumer.complete(req.args, req.args['openid.return_to'])

        css_class = 'error'
        if info.status == consumer.FAILURE and info.identity_url:
            # In the case of failure, if info is non-None, it is the
            # URL that we were verifying. We include it in the error
            # message to help the user figure out what happened.
            fmt = "Verification of %s failed: %s"
            message = fmt % (cgi.escape(info.identity_url), info.message)
        elif info.status == consumer.SUCCESS:
            # Success means that the transaction completed without
            # error. If info is None, it means that the user cancelled
            # the verification.
            css_class = 'alert'

            session_attr = {}  # attributes for new "user"

            # This is a successful verification attempt. If this
            # was a real application, we would do our login,
            # comment posting, etc. here.
            fmt = "You have successfully verified %s as your identity."
            message = fmt % (cgi.escape(info.identity_url), )
            remote_user = info.identity_url

            sreg_info = sreg.SRegResponse.fromSuccessResponse(info) or {}

            ax_response = ax.FetchResponse.fromSuccessResponse(info)
            ax_info = {}
            if ax_response:
                for alias, uri in self.openid_ax_attrs.items():
                    values = ax_response.data.get(uri, [])
                    if values:
                        ax_info[alias] = values[0]

            email = (ax_info.get('email') or ax_info.get('email2')
                     or sreg_info.get('email'))

            fullname = (' '.join(
                filter(None, map(ax_info.get, ('firstname', 'lastname'))))
                        or sreg_info.get('fullname') or
                        (email
                         and email.split('@', 1)[0].replace('.', ' ').title()))

            nickname = sreg_info.get('nickname')

            if self.groups_to_request and TeamsResponse:
                teams_response = TeamsResponse.fromSuccessResponse(info)
                if teams_response:
                    # be careful not to make user a member of any trac groups
                    # not named in groups_to_request
                    teams = set(teams_response.teams).intersection(
                        self.groups_to_request)
                    if teams:
                        session_attr['openid.teams'] = ','.join(teams)

            if self.strip_protocol:
                remote_user = remote_user[remote_user.find('://') + 3:]
            if self.strip_trailing_slash and remote_user[-1] == '/':
                remote_user = remote_user[:-1]
            if info.endpoint.canonicalID:
                # You should authorize i-name users by their canonicalID,
                # rather than their more human-friendly identifiers.  That
                # way their account with you is not compromised if their
                # i-name registration expires and is bought by someone else.
                message += (
                    "  This is an i-name, and its persistent ID is %s" %
                    (cgi.escape(info.endpoint.canonicalID), ))
                remote_user = info.endpoint.canonicalID

            allowed = True
            if self.re_white_list:
                self.env.log.debug(
                    "Filtering REMOTE_USER '%s' through white-list." %
                    remote_user)
                allowed = False
                for item in self.re_white_list:
                    if not allowed and item.match(remote_user):
                        allowed = True
                        self.env.log.debug("User white-listed.")
            if allowed and self.re_black_list:
                self.env.log.debug(
                    "Filtering REMOTE_USER '%s' through black-list." %
                    remote_user)
                for item in self.re_black_list:
                    if item.match(remote_user):
                        allowed = False
                        self.env.log.debug("User black-listed.")
            if allowed and self.re_email_white_list:
                self.env.log.debug(
                    "Filtering email %r through email white-list." % email)
                allowed = False
                if email:
                    for item in self.re_email_white_list:
                        if not allowed and item.match(email):
                            allowed = True
                            self.env.log.debug("User email white-listed.")

            if allowed and self.check_list:
                allowed = False
                params = {self.check_list_key: remote_user}
                if email:
                    params['email'] = email
                url = self.check_list + '?' + urllib.urlencode(params)
                self.env.log.debug('OpenID check list URL: %s' % url)
                try:
                    result = json.load(urllib.urlopen(url))
                    if result[self.check_list_key]:
                        if self.check_list_username:
                            cl_username = unicode(
                                result[self.check_list_username])
                            if not cl_username:
                                raise ValueError("Bad value for username")
                        allowed = True
                except Exception, ex:
                    self.env.log.error('OpenID check_list failed: %s' % ex)

            if allowed:
                cookie = hex_entropy()
                cookie_lifetime = self.trac_auth_cookie_lifetime

                req.outcookie['trac_auth'] = cookie
                req.outcookie['trac_auth']['path'] = req.href()
                if cookie_lifetime > 0:
                    req.outcookie['trac_auth']['expires'] = cookie_lifetime

                session_attr[
                    self.openid_session_identity_url_key] = info.identity_url
                if email:
                    session_attr['email'] = email
                if fullname:
                    session_attr['name'] = fullname

                self._commit_oidsession(oidsession, req)

                if self.check_list and self.check_list_username:
                    authname = cl_username
                elif self.use_nickname_as_authname and nickname:
                    authname = nickname
                elif session_attr.get('name'):
                    authname = session_attr['name']
                    if self.combined_username:
                        authname = '%s <%s>' % (authname, remote_user)
                else:
                    authname = remote_user

                # Possibly lower-case the authname.
                if self.lowercase_authname:
                    authname = authname.lower()

                if self.trust_authname:
                    ds = DetachedSession(self.env, authname)
                else:
                    # Make authname unique in case of collisions
                    #
                    # XXX: We ought to first look for an existing authenticated
                    # session with matching identity_url, and just use that
                    # for the authid.  (E.g. what if the user changes his
                    # fullname at the openid provider?)  However, trac does
                    # not seem to provide an API for searching sessions other
                    # than by sid/authname.
                    #
                    def authnames(base):
                        yield base
                        for attempt in itertools.count(2):
                            yield "%s (%d)" % (base, attempt)

                    existing_users_and_groups = set(
                        user for user, perm in PermissionSystem(
                            self.env).get_all_permissions())

                    for authname in authnames(authname):
                        ds = DetachedSession(self.env, authname)
                        if ds.last_visit == 0 and len(ds) == 0:
                            # At least in 0.12.2, this mean no session exists.
                            if authname in existing_users_and_groups:
                                # Permissions are already defined for this user
                                continue
                            break
                        ds_identity = ds.get(
                            self.openid_session_identity_url_key)
                        if ds_identity == info.identity_url:
                            # No collision
                            break

                if ds and (ds.last_visit != 0 or len(ds) > 0):
                    # The user already exists, update team membership
                    # XXX: Should also update name and/or email? (This would
                    # be an API change.)
                    for name in ['openid.teams']:
                        if name in session_attr:
                            ds[name] = session_attr[name]
                        elif name in ds:
                            del ds[name]
                    ds.save()
                else:
                    # We are creating a new "user".  Set attributes on the
                    # current anonymous session.  It will be promoted to
                    # the new authenticated session on the next request
                    # (by Session.__init__).
                    #
                    # NB: avoid dict.update here to ensure that
                    # DetachedSession.__getitem__ gets a chance to
                    # normalize values
                    for name, value in session_attr.items():
                        req.session[name] = value

                req.authname = authname

                db = self.env.get_db_cnx()
                cursor = db.cursor()
                cursor.execute(
                    "INSERT INTO auth_cookie (cookie,name,ipnr,time) "
                    "VALUES (%s, %s, %s, %s)",
                    (cookie, authname, self._get_masked_address(
                        req.remote_addr), int(time.time())))
                db.commit()

                req.redirect(
                    req.session.get('oid.referer') or self.env.abs_href())
            else:
                message = 'You are not allowed here.'
Exemplo n.º 24
0
 def get_permission_groups(self, username):
     ds = DetachedSession(self.env, username)
     return ds.get('openid.teams', '').split(',')
Exemplo n.º 25
0
 def _add_session(self, sid, **attrs):
     session = DetachedSession(self.env, sid)
     for name, value in attrs.iteritems():
         session[name] = value
     session.save()
Exemplo n.º 26
0
 def test_find_session(self, env, userdb):
     ds = DetachedSession(env, 'foo')
     ds['trac_oidc.subject'] = 'https://example.net?sub=42'
     ds.save()
     sid = userdb.find_session({'iss': 'https://example.net', 'sub': '42'})
     assert sid == 'foo'
Exemplo n.º 27
0
 def test_associate_session(self, env, userdb):
     userdb.associate_session('foo', 'https://example.net', '42')
     ds = DetachedSession(env, 'foo')
     assert ds[userdb.SUBJECT_SKEY] == 'https://example.net?sub=42'
Exemplo n.º 28
0
 def make_session(sid, last_visit):
     monkeypatch.setattr("time.time", lambda: last_visit)
     ds = DetachedSession(env, sid)
     ds['bar'] = 'baz'
     ds.save()
Exemplo n.º 29
0
 def test_create_session(self, env, helper):
     sid = helper.create_session('foo', {'name': 'Joe'})
     assert sid == 'foo'
     ds = DetachedSession(env, 'foo')
     assert ds['name'] == 'Joe'