This file is indexed.

/usr/share/pyshared/acct_mgr/model.py is in trac-accountmanager 0.4.3-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Steffen Hoffmann <hoff.st@web.de>
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.
#
# Author: Steffen Hoffmann <hoff.st@web.de>

from acct_mgr.hashlib_compat  import md5

_USER_KEYS = {
    'auth_cookie': 'name',
    'permission': 'username',
    }


# Public functions

def email_associated(env, email, db=None):
    """Returns whether an authenticated user account with that email address
    exists.
    """
    db = _get_db(env, db)
    cursor = db.cursor()
    cursor.execute("""
        SELECT value
          FROM session_attribute
         WHERE authenticated=1 AND name='email' AND value=%s
        """, (email,))
    for row in cursor:
        return True
    return False

def email_verified(env, user, email, db=None):
    """Returns whether the account and email has been verified.

    Use with care, as it returns the private token string,
    if verification is pending.
    """
    if not user_known(env, user) or not email:
        # Nothing more to check here.
        return None
    db = _get_db(env, db)
    cursor = db.cursor()
    cursor.execute("""
        SELECT value
          FROM session_attribute
         WHERE sid=%s AND name='email_verification_sent_to'
        """, (user,))
    for row in cursor:
        env.log.debug('AcctMgr:model:email_verified for user \"' + \
            user + '\", email \"' + str(email) + '\": ' + str(row[0]))
        if row[0] != email:
            # verification has been sent to different email address
            return None
    cursor.execute("""
        SELECT value
          FROM session_attribute
         WHERE sid=%s AND name='email_verification_token'
        """, (user,))
    for row in cursor:
        # verification token still unverified
        env.log.debug('AcctMgr:model:email_verified for user \"' + \
            user + '\", email \"' + str(email) + '\": ' + str(row[0]))
        return row[0]
    return True

def user_known(env, user, db=None):
    """Returns whether the user has ever been authenticated before."""
    db = _get_db(env, db)
    cursor = db.cursor()
    cursor.execute("""
        SELECT 1
          FROM session
         WHERE authenticated=1 AND sid=%s
        """, (user,))
    for row in cursor:
        return True
    return False


# Utility functions

def get_user_attribute(env, username=None, authenticated=1, attribute=None,
                       value=None, db=None):
    """Return user attributes."""
    ALL_COLS = ('sid', 'authenticated', 'name', 'value')
    columns = []
    constraints = []
    if username is not None:
        columns.append('sid')
        constraints.append(username)
    if authenticated is not None:
        columns.append('authenticated')
        constraints.append(authenticated)
    if attribute is not None:
        columns.append('name')
        constraints.append(attribute)
    if value is not None:
        columns.append('value')
        constraints.append(value)
    sel_columns = [col for col in ALL_COLS if col not in columns]
    if len(sel_columns) == 0:
        # No variable left, so only COUNTing is as a sensible task here. 
        sel_stmt = 'COUNT(*)'
    else:
        if 'sid' not in sel_columns:
            sel_columns.append('sid')
        sel_stmt = ','.join(sel_columns)
    if len(columns) > 0:
        where_stmt = ''.join(['WHERE ', '=%s AND '.join(columns), '=%s'])
    else:
        where_stmt = ''
    sql = """
        SELECT  %s
          FROM  session_attribute
        %s
        """ % (sel_stmt, where_stmt)
    sql_args = tuple(constraints)

    db = _get_db(env, db)
    cursor = db.cursor()
    cursor.execute(sql, sql_args)
    rows = cursor.fetchall()
    if rows is None:
        return {}
    res = {}
    for row in rows:
        if sel_stmt == 'COUNT(*)':
            return [row[0]]
        res_row = {}
        res_row.update(zip(sel_columns, row))
        # Merge with constraints, that are constants for this SQL query.
        res_row.update(zip(columns, constraints))
        account = res_row.pop('sid')
        authenticated = res_row.pop('authenticated')
        # Create single unique attribute ID.
        m = md5()
        m.update(''.join([account, str(authenticated),
                           res_row.get('name')]).encode('utf-8'))
        row_id = m.hexdigest()
        if account in res:
            if authenticated in res[account]:
                res[account][authenticated].update({
                    res_row['name']: res_row['value']
                })
                res[account][authenticated]['id'].update({
                    res_row['name']: row_id
                })
            else:
                res[account][authenticated] = {
                    res_row['name']: res_row['value'],
                    'id': {res_row['name']: row_id}
                }
                # Create account ID for additional authentication state.
                m = md5()
                m.update(''.join([account,
                                  str(authenticated)]).encode('utf-8'))
                res[account]['id'][authenticated] = m.hexdigest()
        else:
            # Create account ID for authentication state.
            m = md5()
            m.update(''.join([account, str(authenticated)]).encode('utf-8'))
            res[account] = {authenticated: {res_row['name']: res_row['value'],
                                            'id': {res_row['name']: row_id}},
                            'id': {authenticated: m.hexdigest()}}
    return res

def prime_auth_session(env, username, db=None):
    """Prime session for registered users before initial login.

    These days there's no distinct user object in Trac, but users consist
    in terms of anonymous or authenticated sessions and related session
    attributes.  So INSERT new sid, needed as foreign key in some db schemata
    later on, at least for PostgreSQL.
    """
    db = _get_db(env, db)
    cursor = db.cursor()
    cursor.execute("""
        SELECT COUNT(*)
          FROM session
         WHERE sid=%s
        """, (username,))
    exists = cursor.fetchone()
    if not exists[0]:
        cursor.execute("""
            INSERT INTO session
                    (sid,authenticated,last_visit)
            VALUES  (%s,1,0)
            """, (username,))
        db.commit()

def set_user_attribute(env, username, attribute, value, db=None):
    """Set or update a Trac user attribute within an atomic db transaction."""
    db = _get_db(env, db)
    cursor = db.cursor()
    sql = """
        WHERE   sid=%s
            AND authenticated=1
            AND name=%s
        """
    cursor.execute("""
        UPDATE  session_attribute
            SET value=%s
        """ + sql, (value, username, attribute))
    cursor.execute("""
        SELECT  value
          FROM  session_attribute
        """ + sql, (username, attribute))
    if cursor.fetchone() is None:
        cursor.execute("""
            INSERT INTO session_attribute
                    (sid,authenticated,name,value)
            VALUES  (%s,1,%s,%s)
            """, (username, attribute, value))
    db.commit()

def del_user_attribute(env, username=None, authenticated=1, attribute=None,
                       db=None):
    """Delete one or more Trac user attributes for one or more users."""
    columns = []
    constraints = []
    if username is not None:
        columns.append('sid')
        constraints.append(username)
    if authenticated is not None:
        columns.append('authenticated')
        constraints.append(authenticated)
    if attribute is not None:
        columns.append('name')
        constraints.append(attribute)
    if len(columns) > 0:
        where_stmt = ''.join(['WHERE ', '=%s AND '.join(columns), '=%s'])
    else:
        where_stmt = ''
    sql = """
        DELETE
        FROM    session_attribute
        %s
        """ % where_stmt
    sql_args = tuple(constraints)

    db = _get_db(env, db)
    cursor = db.cursor()
    cursor.execute(sql, sql_args)
    db.commit()

def delete_user(env, user, db=None):
    # Delete session attributes, session and any custom permissions
    # set for the user.
    db = _get_db(env, db)
    cursor = db.cursor()
    for table in ['auth_cookie', 'session_attribute', 'session', 'permission']:
        # Preseed, since variable table and column names aren't allowed
        # as SQL arguments (security measure agains SQL injections).
        sql = """
            DELETE
              FROM %s
             WHERE %s=%%s
            """ % (table, _USER_KEYS.get(table, 'sid'))
        cursor.execute(sql, (user,))
    db.commit()
    # DEVEL: Is this really needed?
    db.close()
    env.log.debug("Purged session data and permissions for user '%s'" % user)

def last_seen(env, user=None, db=None):
    db = _get_db(env, db)
    cursor = db.cursor()
    sql = """
        SELECT sid,last_visit
          FROM session
         WHERE authenticated=1
        """
    if user:
        sql += " AND sid=%s"
        cursor.execute(sql, (user,))
    else:
        cursor.execute(sql)
    # Don't pass over the cursor (outside of scope), only it's content.
    res = []
    for row in cursor:
        res.append(row)
    return not len(res) == 0 and res or None


# Internal functions

def _get_db(env, db=None):
    return db or env.get_db_cnx()