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->{url} || $userinfo->{username};
83 my $password = $userinfo->{password};
85 return unless ($username =~ /^https?:/
86 || ($username && $self->validate_password($password))) ;
88 my $user = Text::Tradition::User->new(
90 password => ($password ? crypt_password($password) : ''),
93 my $scope = $self->new_scope;
94 $self->store($user->kiokudb_object_id, $user);
101 return $self->add_user(@_);
106 Takes a hashref of C<username>, optionally C<openid_identifier>.
108 Fetches the user object for the given username and returns it.
113 my ($self, $userinfo) = @_;
115 # 'display' => 'castaway.myopenid.com',
116 # 'url' => 'http://castaway.myopenid.com/',
117 my $username = $userinfo->{url} || $userinfo->{username};
119 my $scope = $self->new_scope;
120 return $self->lookup(Text::Tradition::User->id_for_user($username));
126 Takes a hashref of C<username> and C<password> (same as add_user).
128 Retrieves the user, and updates it with the new information. Username
129 changing is not currently supported.
131 Returns the updated user object, or undef if not found.
136 my ($self, $userinfo) = @_;
137 my $username = $userinfo->{username};
138 my $password = $userinfo->{password};
140 return unless $username && $self->validate_password($password);
142 my $user = $self->find_user({ username => $username });
145 my $scope = $self->new_scope;
146 $user->password(crypt_password($password));
148 $self->update($user);
153 =head3 deactivate_user
155 Takes a hashref of C<username>.
157 Sets the users C<active> flag to false (0), and sets all traditions
158 assigned to them to non-public, updates the storage and returns the
161 Returns undef if user not found.
165 sub deactivate_user {
166 my ($self, $userinfo) = @_;
167 my $username = $userinfo->{username};
169 return if !$username;
171 my $user = $self->find_user({ username => $username });
175 foreach my $tradition (@{ $user->traditions }) {
176 ## Not implemented yet
177 # $tradition->public(0);
179 my $scope = $self->new_scope;
181 ## Should we be using Text::Tradition::Directory also?
182 $self->update(@{ $user->traditions });
184 $self->update($user);
189 =head3 reactivate_user
191 Takes a hashref of C<username>.
193 Returns the user object if already activated. Activates (sets the
194 active flag to true (1)), updates the storage and returns the user.
196 Returns undef if the user is not found.
200 sub reactivate_user {
201 my ($self, $userinfo) = @_;
202 my $username = $userinfo->{username};
204 return if !$username;
206 my $user = $self->find_user({ username => $username });
209 return $user if $user->active;
212 my $scope = $self->new_scope;
213 $self->update($user);
220 CAUTION: Delets actual data!
222 Takes a hashref of C<username>.
224 Returns undef if the user doesn't exist.
226 Removes the user from the store and returns 1.
231 my ($self, $userinfo) = @_;
232 my $username = $userinfo->{username};
234 return if !$username;
236 my $user = $self->find_user({ username => $username });
239 my $scope = $self->new_scope;
241 ## Should we be using Text::Tradition::Directory for this bit?
242 $self->delete( @{ $user->traditions });
245 $self->delete($user);
250 =head3 validate_password
252 Takes a password string. Returns true if it is longer than
253 L</MIN_PASS_LEN>, false otherwise.
255 Used internally by L</add_user>.
259 sub validate_password {
260 my ($self, $password) = @_;
262 return if !$password;
263 return if length($password) < $self->MIN_PASS_LEN;