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
|
# -*- coding: utf8 -*-
#
# Copyright (C) 2007 Matthew Good <trac@matt-good.net>
#
# "THE BEER-WARE LICENSE" (Revision 42):
# <trac@matt-good.net> wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return. Matthew Good
#
# Author: Matthew Good <trac@matt-good.net>
from trac.core import *
from trac.config import ExtensionOption
from api import IPasswordStore
from pwhash import IPasswordHashMethod
class SessionStore(Component):
implements(IPasswordStore)
hash_method = ExtensionOption('account-manager', 'hash_method',
IPasswordHashMethod, 'HtDigestHashMethod')
def get_users(self):
"""Returns an iterable of the known usernames
"""
db = self.env.get_db_cnx()
cursor = db.cursor()
cursor.execute("SELECT DISTINCT sid FROM session_attribute "
"WHERE authenticated=1 AND name='password'")
for sid, in cursor:
yield sid
def has_user(self, user):
db = self.env.get_db_cnx()
cursor = db.cursor()
cursor.execute("SELECT * FROM session_attribute "
"WHERE authenticated=1 AND name='password' "
"AND sid=%s", (user,))
for row in cursor:
return True
return False
def set_password(self, user, password):
"""Sets the password for the user. This should create the user account
if it doesn't already exist.
Returns True if a new account was created, False if an existing account
was updated.
"""
hash = self.hash_method.generate_hash(user, password)
db = self.env.get_db_cnx()
cursor = db.cursor()
cursor.execute("UPDATE session_attribute "
"SET value=%s "
"WHERE authenticated=1 AND name='password' "
"AND sid=%s", (hash, user))
if cursor.rowcount > 0:
db.commit()
return False # updated existing password
cursor.execute("INSERT INTO session_attribute "
"(sid,authenticated,name,value) "
"VALUES (%s,1,'password',%s)",
(user, hash))
db.commit()
return True
def check_password(self, user, password):
"""Checks if the password is valid for the user.
"""
db = self.env.get_db_cnx()
cursor = db.cursor()
cursor.execute("SELECT value FROM session_attribute "
"WHERE authenticated=1 AND name='password' "
"AND sid=%s", (user,))
for hash, in cursor:
return self.hash_method.check_hash(user, password, hash)
return False
def delete_user(self, user):
"""Deletes the user account.
Returns True if the account existed and was deleted, False otherwise.
"""
if not self.has_user(user):
return False
db = self.env.get_db_cnx()
cursor = db.cursor()
cursor.execute("DELETE FROM session_attribute "
"WHERE authenticated=1 AND name='password' "
"AND sid=%s", (user,))
# TODO cursor.rowcount doesn't seem to get # deleted
# is there another way to get count instead of using has_user?
db.commit()
return True
|