summaryrefslogtreecommitdiff
path: root/lib/VNWeb/User
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2019-09-30 18:05:28 +0200
committerYorhel <git@yorhel.nl>2019-09-30 18:05:41 +0200
commit2d7e855cfb37f35cb2cd0f8f39754002c20c8a7c (patch)
treeb1ff536adee289c3b6e1a56c1f1a71acd1da6c87 /lib/VNWeb/User
parent24e08e0f2caf8dede4a0c8a77b8ede1e13899785 (diff)
v2rw: Convert login, logout & insecure-password-change forms
The insecure-password-change flow is now slightly more friendly. The logout functionality has been hardened to use POST and require CSRF.
Diffstat (limited to 'lib/VNWeb/User')
-rw-r--r--lib/VNWeb/User/Login.pm69
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/VNWeb/User/Login.pm b/lib/VNWeb/User/Login.pm
new file mode 100644
index 00000000..bd8f75ab
--- /dev/null
+++ b/lib/VNWeb/User/Login.pm
@@ -0,0 +1,69 @@
+package VNWeb::User::Login;
+
+use VNWeb::Prelude;
+
+
+my $LOGIN = form_compile in => {
+ username => { username => 1 },
+ password => { password => 1 }
+};
+
+elm_form UserLogin => $LOGIN, $LOGIN;
+
+
+TUWF::get '/u/login' => sub {
+ return tuwf->resRedirect('/', 'temp') if auth;
+
+ my $ref = tuwf->reqGet('ref');
+ $ref = '/' if !$ref || $ref !~ /^\//;
+
+ framework_ title => 'Login', index => 0, sub {
+ elm_ 'User.Login' => tuwf->compile({}), $ref;
+ };
+};
+
+
+json_api '/u/login', $LOGIN, sub {
+ my $data = shift;
+
+ my $ip = norm_ip tuwf->reqIP;
+ my $tm = tuwf->dbVali(
+ 'SELECT', sql_totime('greatest(timeout, now())'), 'FROM login_throttle WHERE ip =', \$ip
+ ) || time;
+ return elm_LoginThrottle if $tm-time() > config->{login_throttle}[1];
+
+ my $insecure = is_insecurepass $data->{password};
+ return $insecure ? elm_InsecurePass : elm_Success
+ if auth->login($data->{username}, $data->{password}, $insecure);
+
+ # Failed login, update throttle.
+ my $upd = {
+ ip => \$ip,
+ timeout => sql_fromtime $tm + config->{login_throttle}[0]
+ };
+ tuwf->dbExeci('INSERT INTO login_throttle', $upd, 'ON CONFLICT (ip) DO UPDATE SET', $upd);
+ elm_BadLogin
+};
+
+
+json_api '/u/changepass', {
+ username => { username => 1 },
+ oldpass => { password => 1 },
+ newpass => { password => 1 },
+}, sub {
+ my $data = shift;
+ my $uid = tuwf->dbVali('SELECT id FROM users WHERE username =', \$data->{username});
+ die if !$uid;
+ return elm_InsecurePass if is_insecurepass $data->{newpass};
+ die if !auth->setpass($uid, undef, $data->{oldpass}, $data->{newpass}); # oldpass should already have been verified.
+ elm_Success
+};
+
+
+TUWF::post qr{/$RE{uid}/logout}, sub {
+ return tuwf->resNotFound if !auth || auth->uid != tuwf->capture('id') || (tuwf->reqPost('csrf')||'') ne auth->csrftoken;
+ auth->logout;
+ tuwf->resRedirect('/', 'post');
+};
+
+1;