1 package Newslash::Plugin::Users;
2 use Mojo::Base 'Mojolicious::Plugin';
10 my ($self, $app, $conf) = @_;
12 $app->helper(users => sub { state $users = $self; });
14 # default config values
15 my $cnf = $app->config->{Users} ||= {};
16 $cnf->{newpasswd_expiration} ||= 60 * 60 * 24; # 60[sec] * 60[min] * 24[hour]
20 my ($self, $user) = @_;
22 $self->app->event_que->emit("user", "resetpw", $user->{uid}, $user->{uid});
26 sub cancel_activation {
27 my ($self, $user) = @_;
28 my $users = $self->app->model('users');
30 my $rs = $users->update(uid => $user->{uid},
32 newpasswd_ts => {function => "NULL"});
34 $self->app->log->error("Users: newpasswd reset error! uid: $user->{uid}");
35 $self->last_error($users->last_error);
41 sub update_password_by_token {
42 my ($self, $nickname, $token, $password) = @_;
44 # check nickname and token pair
45 my $the_user = $self->activation($nickname, $token);
48 return $self->_update_password($the_user, $password);
52 my ($self, $user, $old_password, $new_password) = @_;
56 sub _update_password {
57 my ($self, $the_user, $password) = @_;
58 my $users = $self->app->model('users');
60 my @params = (uid => $the_user->{uid},
61 passwd => $password );
63 if ($the_user->{seclev} < 1) {
64 push @params, seclev => 1;
67 if ($the_user->{newpasswd}) {
68 push @params, newpasswd => "";
69 push @params, newpasswd_ts => { function => "NULL" };
72 my $rs = $users->update(@params);
75 $self->last_error($users->last_error);
83 my ($self, $nickname, $token) = @_;
84 return if (!$nickname || !$token);
86 my $users = $self->app->model('users');
87 my $the_user = $users->select(nickname => $nickname);
89 # check if token is correct
91 || !$users->passwords->compare_password($token, $the_user->{newpasswd})
92 || !$the_user->{newpasswd_ts}) {
93 $self->last_error("INVALID_TOKEN");
97 # check if token is expired
98 my $expiration_limit = $self->app->config->{Users}->{newpasswd_expiration};
99 my $expire_dt = eval { DateTime::Format::MySQL->parse_datetime($the_user->{newpasswd_ts}) };
101 $self->app->log->error("Users: invalid newpasswd_ts ($the_user->{newpasswd_ts}). uid: $the_user->{uid}");
102 $self->last_error("INVALID_TOKEN");
105 $expire_dt->add( seconds => $expiration_limit);
106 if ($expire_dt->epoch() < time()) {
107 $self->last_error("TOKEN_EXPIRED");
115 sub create_new_user {
116 my ($self, $nickname, $email, $options) = @_;
117 my $users = $self->app->model('users');
120 # check $nickname and $email
121 my ($id_error, $email_error) = $self->validate_new_user($nickname, $email);
122 if ($id_error || $email_error) {
123 $self->last_error({ id_error => $id_error,
124 email_error => $email_error });
128 my $uid = $users->create($nickname, $email, "", { seclev => 0 });
131 $self->last_error({ id_error => $id_error,
132 email_error => $email_error,
133 system_error => $users->last_error });
138 if ($options->{message}) {
139 my $message_types = $self->app->model('messages');
140 for my $k (keys %{$options->{message}}) {
141 my $rs = $users->messages->update(uid => $uid,
143 mode => $options->{message}->{$k});
145 $self->app->log->error("Users: message update failed! uid: $uid, name: $k, mode: $options->{message}->{$k}");
150 $self->app->event_que->emit("user", "create", $uid, $uid);
154 sub validate_new_user {
155 my ($self, $nickname, $email) = @_;
156 my $nick_regex = qr/^[a-zA-Z_][ a-zA-Z0-9\$_.+!*\'(),-]{0,19}$/;
157 my $users = $self->app->model('users');
159 my ($id_error, $email_error);
160 $id_error = "BLANK_ID" if !$nickname;
161 $email_error = "BLANK_EMAIL" if !$email;
165 if ($nickname =~ $nick_regex) {
166 my $matchname = $users->nickname_to_matchname($nickname);
167 my $rs = $users->select(matchname => $matchname);
169 $id_error = "ID_EXISTS";
173 $id_error = "INVALID_ID";
178 if (Email::Valid->address($email)) {
179 my $rs = $users->select(realemail => $email);
181 $email_error = "EMAIL_EXISTS";
185 $email_error = "INVALID_EMAIL";
189 if ($id_error || $email_error) {
190 $self->last_error({id_error => $id_error, email_error => $email_error});
203 Newslash::Plugin::Users - Newslash users manipulation plugin
208 $app->plugin('Newslash::Plugin::Users');
212 L<Newslash::Plugin::Users> is 'Business Logic' layer of Newslash.
217 L<Mojolicious::Plugin::Users> implements the following helpers.
221 [% helpers.boxes() %]
223 Fetch box contents for current user and returns them.
225 =head2 format_timestamp
227 $c->format_timestamp(user => $user, epoch => $epoch, format => "user")
228 $c->format_timestamp(datetime => $dt, format => "simple")
230 Return formated string.
236 $plugin->register(Mojolicious->new);
238 Register helpers in L<Mojolicious> application.
240 =head2 validate_new_user
242 my ($id_error, $email_error) = $plugin->validate_new_user($nickname, $email);
244 Check nickname and email address are not registered.
246 $id_error is one of below string or undef (no error).
252 $email_error is one of below string or undef (no error).
261 L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicious.org>.