1 module vibeauth.authenticators.oauth.PasswordGrantAccess; 2 3 import vibeauth.authenticators.oauth.IGrantAccess; 4 import vibeauth.authenticators.oauth.AuthData; 5 import vibeauth.collections.usercollection; 6 7 import std.datetime; 8 import std.array; 9 10 import vibe.data.json; 11 12 /// Grant user access based on username and password strings 13 final class PasswordGrantAccess : IGrantAccess { 14 private { 15 AuthData data; 16 UserCollection collection; 17 } 18 19 /// setter for the authentication data 20 void authData(AuthData authData) { 21 this.data = authData; 22 } 23 24 /// setter for the user collection 25 void userCollection(UserCollection userCollection) { 26 this.collection = userCollection; 27 } 28 29 /// validate the authentication data 30 bool isValid() { 31 if(!collection.contains(data.username)) { 32 return false; 33 } 34 35 if(!collection[data.username].isValidPassword(data.password)) { 36 return false; 37 } 38 39 return true; 40 } 41 42 /// Get the token Json response object 43 Json get() { 44 auto response = Json.emptyObject; 45 46 if(!isValid) { 47 response["error"] = "Invalid password or username"; 48 return response; 49 } 50 51 auto now = Clock.currTime; 52 53 auto user = collection[data.username]; 54 foreach(token; user.getTokensByType("Bearer").array) { 55 if(token.expire < now) { 56 user.revoke(token.name); 57 } 58 } 59 60 foreach(token; user.getTokensByType("Refresh").array) { 61 if(token.expire < now) { 62 user.revoke(token.name); 63 } 64 } 65 66 67 auto accessToken = collection.createToken(data.username, Clock.currTime + 3601.seconds, data.scopes, "Bearer"); 68 auto refreshToken = collection.createToken(data.username, Clock.currTime + 4.weeks, data.scopes ~ [ "refresh" ], "Refresh"); 69 70 response["access_token"] = accessToken.name; 71 response["expires_in"] = (accessToken.expire - Clock.currTime).total!"seconds"; 72 response["token_type"] = accessToken.type; 73 response["refresh_token"] = refreshToken.name; 74 75 return response; 76 } 77 }