3
# Copyright (C) 2007 Matthew Good <trac@matt-good.net>
5
# "THE BEER-WARE LICENSE" (Revision 42):
6
# <trac@matt-good.net> wrote this file. As long as you retain this notice you
7
# can do whatever you want with this stuff. If we meet some day, and you think
8
# this stuff is worth it, you can buy me a beer in return. Matthew Good
10
# Author: Matthew Good <trac@matt-good.net>
12
from trac.core import *
13
from trac.config import ExtensionOption
15
from api import IPasswordStore
16
from pwhash import IPasswordHashMethod
18
class SessionStore(Component):
19
implements(IPasswordStore)
21
hash_method = ExtensionOption('account-manager', 'hash_method',
22
IPasswordHashMethod, 'HtDigestHashMethod')
25
"""Returns an iterable of the known usernames
27
db = self.env.get_db_cnx()
29
cursor.execute("SELECT DISTINCT sid FROM session_attribute "
30
"WHERE authenticated=1 AND name='password'")
34
def has_user(self, user):
35
db = self.env.get_db_cnx()
37
cursor.execute("SELECT * FROM session_attribute "
38
"WHERE authenticated=1 AND name='password' "
39
"AND sid=%s", (user,))
44
def set_password(self, user, password):
45
"""Sets the password for the user. This should create the user account
46
if it doesn't already exist.
47
Returns True if a new account was created, False if an existing account
50
hash = self.hash_method.generate_hash(user, password)
51
db = self.env.get_db_cnx()
53
cursor.execute("UPDATE session_attribute "
55
"WHERE authenticated=1 AND name='password' "
56
"AND sid=%s", (hash, user))
57
if cursor.rowcount > 0:
59
return False # updated existing password
60
cursor.execute("INSERT INTO session_attribute "
61
"(sid,authenticated,name,value) "
62
"VALUES (%s,1,'password',%s)",
67
def check_password(self, user, password):
68
"""Checks if the password is valid for the user.
70
db = self.env.get_db_cnx()
72
cursor.execute("SELECT value FROM session_attribute "
73
"WHERE authenticated=1 AND name='password' "
74
"AND sid=%s", (user,))
76
return self.hash_method.check_hash(user, password, hash)
79
def delete_user(self, user):
80
"""Deletes the user account.
81
Returns True if the account existed and was deleted, False otherwise.
83
if not self.has_user(user):
85
db = self.env.get_db_cnx()
87
cursor.execute("DELETE FROM session_attribute "
88
"WHERE authenticated=1 AND name='password' "
89
"AND sid=%s", (user,))
90
# TODO cursor.rowcount doesn't seem to get # deleted
91
# is there another way to get count instead of using has_user?