OSDN Git Service

Plugin::Users: add fix to work password and email related function
authorhylom <hylom@users.sourceforge.jp>
Fri, 9 Nov 2018 11:41:27 +0000 (20:41 +0900)
committerhylom <hylom@users.sourceforge.jp>
Fri, 9 Nov 2018 11:41:27 +0000 (20:41 +0900)
src/newslash_web/lib/Newslash/Plugin/Users.pm

index 3203dac..1c55330 100644 (file)
@@ -40,7 +40,7 @@ sub request_change_email {
                          value => $email);
 
     if (!defined $rs) {
-        $self->app->error("Users: update users_param table for change_email failed! uid: $user->{uid}");
+        $self->app->error("Users: update users_param table for request_change_email failed! uid: $user->{uid}");
         $self->last_error($param->last_error);
         return;
     }
@@ -49,39 +49,8 @@ sub request_change_email {
     return 1;
 }
 
-sub reset_password {
-    my ($self, $user) = @_;
-
-    if (!$user || $user->{uid}) {
-        $self->last_error("INVALID_USER");
-        return;
-    }
-
-    $self->app->event_que->emit("user", "reset_password", $user->{uid}, $user->{uid}, 10);
-    return 1;
-}
-
-sub generate_password_reset_token {
-    my ($self, $uid) = @_;
-    my $users = $self->app->model('users');
-
-    # generate new token
-    my $token = $users->passwords->generate_random_password;
-    my $hashed_token = $users->passwords->encrypt_password($token);
-
-    my $rs = $users->update(uid => $uid,
-                            newpasswd => $hashed_token,
-                            newpasswd_ts => { function => "NOW()" });
-    if (!$rs) {
-        $self->last_error($users->last_error);
-        return;
-    }
-
-    return $token;
-}
-
 sub generate_email_change_token {
-    my ($self, $uid, $email) = @_;
+    my ($self, $uid) = @_;
     my $users = $self->app->model('users');
 
     # generate new token
@@ -115,6 +84,135 @@ sub generate_email_change_token {
     return $token;
 }
 
+sub verify_and_change_email {
+    my ($self, $uid, $token) = @_;
+
+    return if (!$uid || !$token);
+    my $users = $self->app->model('users');
+    my $params = $users->param->select(uid => $uid);
+
+    # check if token is expired
+    my $token_ts = $params->{new_email_token_ts};
+    if (!$token_ts) {
+        $self->last_error("INVALID_TOKEN");
+        return;
+    }
+    my $expire_dt = eval { DateTime::Format::MySQL->parse_datetime($token_ts) };
+    my $expiration_limit = $self->app->config->{Users}->{update_email_expiration};
+    if (!$expire_dt) {
+        $self->app->log->error("Users: invalid new_email_token_ts ($token_ts). uid: $uid");
+        $self->last_error("INVALID_TOKEN");
+        return;
+    }
+    $expire_dt->add( seconds => $expiration_limit);
+    if ($expire_dt->epoch() < time()) {
+        $self->last_error("TOKEN_EXPIRED");
+        return;
+    }
+
+    # check token
+    if (!$users->passwords->verify_password(password => $token,
+                                            hashed => $params->{new_email_token})) {
+        $self->last_error("INVALID_TOKEN");
+        return;
+    }
+
+    warn "do update mail";
+
+    # token is valid, so change email
+    my $email = $params->{new_email};
+    if (!$email) {
+        $self->last_error("INVALID_EMAIL");
+        return;
+    }
+    $users->start_transaction;
+    if (!defined $users->update(uid => $uid, realemail => $email)) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    if (!defined $users->param->delete(uid => $uid, name => "new_email")) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    if (!defined $users->param->delete(uid => $uid, name => "new_email_token")) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    if (!defined $users->param->delete(uid => $uid, name => "new_email_token_ts")) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    $users->commit;
+    return 1;
+}
+
+sub cancel_change_email_request {
+    my ($self, $uid) = @_;
+    return if !$uid;
+    my $users = $self->app->model('users');
+    my $params = $users->param->select(uid => $uid);
+
+    my $email = $params->{new_email};
+    if (!$email) {
+        $self->last_error("NO_EMAIL");
+        return;
+    }
+
+    $users->start_transaction;
+    if (!defined $users->param->delete(uid => $uid, name => "new_email")) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    if (!defined $users->param->delete(uid => $uid, name => "new_email_token")) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    if (!defined $users->param->delete(uid => $uid, name => "new_email_token_ts")) {
+        $users->rollback;
+        $self->last_error($users->last_error);
+        return;
+    }
+    $users->commit;
+    return 1;
+
+}
+
+sub reset_password {
+    my ($self, $user) = @_;
+
+    if (!$user || $user->{uid}) {
+        $self->last_error("INVALID_USER");
+        return;
+    }
+
+    $self->app->event_que->emit("user", "reset_password", $user->{uid}, $user->{uid}, 10);
+    return 1;
+}
+
+sub generate_password_reset_token {
+    my ($self, $uid) = @_;
+    my $users = $self->app->model('users');
+
+    # generate new token
+    my $token = $users->passwords->generate_random_password;
+    my $hashed_token = $users->passwords->encrypt_password($token);
+
+    my $rs = $users->update(uid => $uid,
+                            newpasswd => $hashed_token,
+                            newpasswd_ts => { function => "NOW()" });
+    if (!$rs) {
+        $self->last_error($users->last_error);
+        return;
+    }
+
+    return $token;
+}
 
 sub cancel_activation {
     my ($self, $user) = @_;