1 module userauth.services.persona; 2 3 import userauth.userauth; 4 5 import vibe.core.log; 6 import vibe.http.client; 7 import vibe.stream.memory; 8 import vibe.templ.diet; 9 10 11 class PersonaAuthService : UserAuthService { 12 string generateAuthMixin(HTTPServerRequest req, string path_prefix) 13 { 14 logDebug("logged in: %s %s", req.session.id !is null, req.cookies); 15 auto dst = new MemoryOutputStream; 16 string authUserEmail; 17 if (req.session) authUserEmail = req.session.get!string("email"); 18 parseDietFileCompat!("userauth-persona-auth-mixin.dt", 19 string, "path_prefix", 20 string, "authUserEmail")(dst, path_prefix, authUserEmail); 21 return cast(string)dst.data(); 22 } 23 24 void registerRoutes(URLRouter router, string path_prefix) 25 { 26 // NOTE: need to be at root directory because the cookie has to be available 27 // on all pages 28 router.post("/persona-login", &login); 29 router.post("/persona-logout", &logout); 30 } 31 32 private void login(HTTPServerRequest req, HTTPServerResponse res) 33 { 34 enforceHTTP("assertion" in req.form, HTTPStatus.BadRequest, "'assertion' field is missing."); 35 36 auto cres = requestHTTP("https://verifier.login.persona.org/verify", (scope creq){ 37 creq.method = HTTPMethod.POST; 38 creq.writeJsonBody(["assertion": req.form["assertion"], "audience": "http://localhost:8080/"]); 39 }); 40 41 enforceHTTP(cres.statusCode == HTTPStatus.OK, HTTPStatus.Unauthorized, "Auth assertion could not be validated."); 42 43 auto jres = cres.readJson(); 44 enforceHTTP(jres.status.get!string == "okay", HTTPStatus.Unauthorized, "Auth assertion is invalid."); 45 46 Session session = req.session; 47 if( !session ) session = res.startSession(); 48 session.set("email", jres.email.get!string); 49 res.writeJsonBody(jres); 50 } 51 52 private void logout(HTTPServerRequest req, HTTPServerResponse res) 53 { 54 if( req.session ) res.terminateSession(); 55 res.writeJsonBody(["message": "Successfully logged out."]); 56 } 57 }