1 package Text::Tradition::UserStore;
7 use KiokuX::User::Util qw(crypt_password);
9 extends 'KiokuX::Model';
11 use Text::Tradition::User;
12 # use Text::Tradition::Directory;
16 Text::Tradition::UserStore - KiokuDB storage management for Users
20 my $userstore = Text::Tradition::UserStore->new(dsn => 'dbi:SQLite:foo.db');
21 my $newuser = $userstore->add_user({ username => 'fred',
22 password => 'somepassword' });
24 my $fetchuser = $userstore->find_user({ username => 'fred' });
25 if($fetchuser->check_password('somepassword')) {
26 ## login user or .. whatever
29 my $user = $userstore->deactivate_user({ username => 'fred' });
31 ## shouldnt be able to login etc
36 A L<KiokuX::Model> for managing the storage and creation of
37 L<Text::Tradition::User> objects. Subclass or replace this module in
38 order to use a different source for stemmaweb users.
44 Inherited from KiokuX::Model - dsn for the data store we are using.
48 Constant for the minimum password length when validating passwords,
53 has MIN_PASS_LEN => ( is => 'ro', isa => 'Num', default => sub { 8 } );
55 # has 'directory' => (
57 # isa => 'KiokuX::Model',
61 ## TODO: Some of these methods should probably optionally take $user objects
62 ## instead of hashrefs.
64 ## It also occurs to me that all these methods don't need to be named
65 ## XX_user, but leaving that way for now incase we merge this code
66 ## into ::Directory for one-store.
68 ## To die or not to die, on error, this is the question.
74 Takes a hashref of C<username>, C<password>.
76 Create a new user object, store in the KiokuDB backend, and return it.
81 my ($self, $userinfo) = @_;
82 my $username = $userinfo->{username};
83 my $password = $userinfo->{password};
85 return unless $username && $self->validate_password($password);
87 my $user = Text::Tradition::User->new(
89 password => crypt_password($password),
92 my $scope = $self->new_scope;
93 $self->store($user->kiokudb_object_id, $user);
100 Takes a hashref of C<username>, optionally C<openid_identifier>.
102 Fetches the user object for the given username and returns it.
107 my ($self, $userinfo) = @_;
109 # 'display' => 'castaway.myopenid.com',
110 # 'url' => 'http://castaway.myopenid.com/',
111 my $username = $userinfo->{url} || $userinfo->{username};
113 my $scope = $self->new_scope;
114 return $self->lookup(Text::Tradition::User->id_for_user($username));
120 Takes a hashref of C<username> and C<password> (same as add_user).
122 Retrieves the user, and updates it with the new information. Username
123 changing is not currently supported.
125 Returns the updated user object, or undef if not found.
130 my ($self, $userinfo) = @_;
131 my $username = $userinfo->{username};
132 my $password = $userinfo->{password};
134 return unless $username && $self->validate_password($password);
136 my $user = $self->find_user({ username => $username });
139 my $scope = $self->new_scope;
140 $user->password(crypt_password($password));
142 $self->update($user);
147 =head3 deactivate_user
149 Takes a hashref of C<username>.
151 Sets the users C<active> flag to false (0), and sets all traditions
152 assigned to them to non-public, updates the storage and returns the
155 Returns undef if user not found.
159 sub deactivate_user {
160 my ($self, $userinfo) = @_;
161 my $username = $userinfo->{username};
163 return if !$username;
165 my $user = $self->find_user({ username => $username });
169 foreach my $tradition (@{ $user->traditions }) {
170 ## Not implemented yet
171 # $tradition->public(0);
173 my $scope = $self->new_scope;
175 ## Should we be using Text::Tradition::Directory also?
176 $self->update(@{ $user->traditions });
178 $self->update($user);
183 =head3 reactivate_user
185 Takes a hashref of C<username>.
187 Returns the user object if already activated. Activates (sets the
188 active flag to true (1)), updates the storage and returns the user.
190 Returns undef if the user is not found.
194 sub reactivate_user {
195 my ($self, $userinfo) = @_;
196 my $username = $userinfo->{username};
198 return if !$username;
200 my $user = $self->find_user({ username => $username });
203 return $user if $user->active;
206 my $scope = $self->new_scope;
207 $self->update($user);
214 CAUTION: Delets actual data!
216 Takes a hashref of C<username>.
218 Returns undef if the user doesn't exist.
220 Removes the user from the store and returns 1.
225 my ($self, $userinfo) = @_;
226 my $username = $userinfo->{username};
228 return if !$username;
230 my $user = $self->find_user({ username => $username });
233 my $scope = $self->new_scope;
235 ## Should we be using Text::Tradition::Directory for this bit?
236 $self->delete( @{ $user->traditions });
239 $self->delete($user);
244 =head3 validate_password
246 Takes a password string. Returns true if it is longer than
247 L</MIN_PASS_LEN>, false otherwise.
249 Used internally by L</add_user>.
253 sub validate_password {
254 my ($self, $password) = @_;
256 return if !$password;
257 return if length($password) < $self->MIN_PASS_LEN;