forked from dweuthen/roundcube-application_passwords
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexample-app_authenticate.sql
99 lines (84 loc) · 3.64 KB
/
example-app_authenticate.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
BEGIN
DECLARE vResetBadPasswordCountAfter int;
DECLARE vLockoutDuration int;
DECLARE vMaxPasswordAttempts int;
DECLARE MatchUser_ID int(10);
DECLARE MatchApp_ID int(10);
DECLARE PasswordAccessResult int;
SET vMaxPasswordAttempts = 10;
SET vResetBadPasswordCountAfter = 10;
SET vLockoutDuration = 10;
IF (vIgnoreWhitespace = 1) THEN
SET vPassword = REPLACE(vPassword,' ','');
END IF;
#find the user by name
SELECT user_id
FROM users
WHERE username = vUsername
INTO MatchUser_ID;
IF (MatchUser_ID IS NOT NULL) THEN
IF NOT EXISTS(SELECT * FROM app_user WHERE user_id = MatchUser_ID) THEN
INSERT INTO app_user (user_id, badpasswordcount, islockedout)
VALUES(MatchUser_ID, 0, 0);
END IF;
#reset bad password account if it has been long enough
UPDATE app_user
SET badpasswordcount = 0
WHERE user_id = MatchUser_ID
AND TIMESTAMPDIFF(MINUTE, lastbadpassword, UTC_TIMESTAMP()) > vResetBadPasswordCountAfter;
#check if the password matches any UserPassword record
SELECT ap.app_id
FROM app_user au
INNER JOIN app_password ap ON ap.user_id = au.user_id
WHERE au.user_id = MatchUser_ID
AND (au.islockedout = 0 OR TIMESTAMPDIFF(MINUTE, au.lastbadpassword, UTC_TIMESTAMP()) > vLockoutDuration)
AND (ap.password = SHA2(CONCAT(ap.salt,vPassword), 512))
INTO MatchApp_ID;
#if the password is incorrect, and the username is not
IF (MatchApp_ID IS NULL AND MatchUser_ID > 0) THEN
#incr account lockout
UPDATE app_user
SET lastbadpassword = UTC_TIMESTAMP(),
badpasswordcount = badpasswordcount + 1
WHERE user_id = MatchUser_ID;
#lockout account after too many bad password attempts
UPDATE app_user
SET islockedout = 1
WHERE user_id = MatchUser_ID
AND islockedout = 0
AND badpasswordcount >= vMaxPasswordAttempts;
INSERT INTO app_log (logdatetime,username,user_id,service,remoteaddress,message)
VALUES(UTC_TIMESTAMP(), vUsername, MatchUser_ID, vService, vRemoteAddress, 'Bad password.');
#else if the password is correct, and the user is matched
ELSEIF (MatchApp_ID > 0 AND MatchUser_ID > 0) THEN
#clear the lockout flag and set the last login date time if the login was successful
UPDATE app_user
SET islockedout = 0,
lastlogin = UTC_TIMESTAMP()
WHERE user_id = MatchUser_ID;
# update the last used date on UserPassword
UPDATE app_password
SET lastlogin = UTC_TIMESTAMP(),
lastaddress = vRemoteAddress
WHERE app_id = MatchApp_ID;
INSERT INTO app_log (logdatetime,username,user_id,service,remoteaddress,message)
VALUES(UTC_TIMESTAMP(), vUsername, MatchUser_ID, vService, vRemoteAddress, 'Logged in');
END IF;
ELSE
INSERT INTO app_log (logdatetime,username,user_id,service,remoteaddress,message)
VALUES(UTC_TIMESTAMP(), vUsername, MatchUser_ID, vService, vRemoteAddress, 'Bad username.');
END IF;
IF (vOutFormat = 'dovecot') THEN
#dovecot format
SELECT NULL AS password,'Y' as nopassword, u.username AS user
FROM users u
WHERE u.user_id = MatchUser_ID
AND MatchApp_ID IS NOT NULL;
ELSE
#generic format where 0 returned rows = fail, nonzero rows equals success
SELECT username
FROM users u
WHERE u.user_id = MatchUser_ID
AND MatchApp_ID IS NOT NULL;
END IF;
END