bool OAuth2Login::requestToken(Request &req, const string &state, const string &redirectURI) { auto handler = [this, &req] (Request &_req) { verifyToken(req, _req.getInput()); }; URI verifyURL = getOAuth2()->getVerifyURL(req.getURI(), state); // Override redirect URI if (!redirectURI.empty()) verifyURL.set("redirect_uri", redirectURI); // Extract query data string data = verifyURL.getQuery(); verifyURL.setQuery(""); // Verify authorization with OAuth2 server SmartPointer<OutgoingRequest> pr = client.call(verifyURL, HTTP_POST, data, handler); pr->setContentType("application/x-www-form-urlencoded"); pr->outSet("Accept", "application/json"); pr->send(); return true; }
void URITest::testConstruction() { URI uri; assert (uri.getScheme().empty()); assert (uri.getAuthority().empty()); assert (uri.getUserInfo().empty()); assert (uri.getHost().empty()); assert (uri.getPort() == 0); assert (uri.getPath().empty()); assert (uri.getQuery().empty()); assert (uri.getFragment().empty()); uri.setScheme("ftp"); assert (uri.getScheme() == "ftp"); assert (uri.getPort() == 21); uri.setScheme("HTTP"); assert (uri.getScheme() == "http"); uri.setAuthority("www.appinf.com"); assert (uri.getAuthority() == "www.appinf.com"); assert (uri.getPort() == 80); uri.setAuthority("[email protected]:8000"); assert (uri.getUserInfo() == "user"); assert (uri.getHost() == "services.appinf.com"); assert (uri.getPort() == 8000); uri.setPath("/index.html"); assert (uri.getPath() == "/index.html"); uri.setPath("/file%20with%20spaces.html"); assert (uri.getPath() == "/file with spaces.html"); uri.setPathEtc("/query.cgi?query=foo"); assert (uri.getPath() == "/query.cgi"); assert (uri.getQuery() == "query=foo"); assert (uri.getFragment().empty()); assert (uri.getPathEtc() == "/query.cgi?query=foo"); assert (uri.getPathAndQuery() == "/query.cgi?query=foo"); uri.setPathEtc("/query.cgi?query=bar#frag"); assert (uri.getPath() == "/query.cgi"); assert (uri.getQuery() == "query=bar"); assert (uri.getFragment() == "frag"); assert (uri.getPathEtc() == "/query.cgi?query=bar#frag"); assert (uri.getPathAndQuery() == "/query.cgi?query=bar"); uri.setQuery("query=test"); assert (uri.getQuery() == "query=test"); uri.setFragment("result"); assert (uri.getFragment() == "result"); URI uri2("file", "/home/guenter/foo.bar"); assert (uri2.getScheme() == "file"); assert (uri2.getPath() == "/home/guenter/foo.bar"); URI uri3("http", "www.appinf.com", "/index.html"); assert (uri3.getScheme() == "http"); assert (uri3.getAuthority() == "www.appinf.com"); assert (uri3.getPath() == "/index.html"); URI uri4("http", "www.appinf.com:8000", "/index.html"); assert (uri4.getScheme() == "http"); assert (uri4.getAuthority() == "www.appinf.com:8000"); assert (uri4.getPath() == "/index.html"); URI uri5("http", "[email protected]:8000", "/index.html"); assert (uri5.getScheme() == "http"); assert (uri5.getUserInfo() == "user"); assert (uri5.getHost() == "www.appinf.com"); assert (uri5.getPort() == 8000); assert (uri5.getAuthority() == "[email protected]:8000"); assert (uri5.getPath() == "/index.html"); URI uri6("http", "[email protected]:80", "/index.html"); assert (uri6.getScheme() == "http"); assert (uri6.getUserInfo() == "user"); assert (uri6.getHost() == "www.appinf.com"); assert (uri6.getPort() == 80); assert (uri6.getAuthority() == "*****@*****.**"); assert (uri6.getPath() == "/index.html"); URI uri7("http", "[email protected]:", "/index.html"); assert (uri7.getScheme() == "http"); assert (uri7.getUserInfo() == "user"); assert (uri7.getHost() == "www.appinf.com"); assert (uri7.getPort() == 80); assert (uri7.getAuthority() == "*****@*****.**"); assert (uri7.getPath() == "/index.html"); URI uri8("http", "www.appinf.com", "/index.html", "query=test"); assert (uri8.getScheme() == "http"); assert (uri8.getAuthority() == "www.appinf.com"); assert (uri8.getPath() == "/index.html"); assert (uri8.getQuery() == "query=test"); URI uri9("http", "www.appinf.com", "/index.html", "query=test", "fragment"); assert (uri9.getScheme() == "http"); assert (uri9.getAuthority() == "www.appinf.com"); assert (uri9.getPath() == "/index.html"); assert (uri9.getPathEtc() == "/index.html?query=test#fragment"); assert (uri9.getQuery() == "query=test"); assert (uri9.getFragment() == "fragment"); uri9.clear(); assert (uri9.getScheme().empty()); assert (uri9.getAuthority().empty()); assert (uri9.getUserInfo().empty()); assert (uri9.getHost().empty()); assert (uri9.getPort() == 0); assert (uri9.getPath().empty()); assert (uri9.getQuery().empty()); assert (uri9.getFragment().empty()); URI uri10("ldap", "[2001:db8::7]", "/c=GB?objectClass?one"); assert (uri10.getScheme() == "ldap"); assert (uri10.getUserInfo().empty()); assert (uri10.getHost() == "2001:db8::7"); assert (uri10.getPort() == 389); assert (uri10.getAuthority() == "[2001:db8::7]"); assert (uri10.getPathEtc() == "/c=GB?objectClass?one"); URI uri11("http", "www.appinf.com", "/index.html?query=test#fragment"); assert (uri11.getScheme() == "http"); assert (uri11.getAuthority() == "www.appinf.com"); assert (uri11.getPath() == "/index.html"); assert (uri11.getPathEtc() == "/index.html?query=test#fragment"); assert (uri11.getQuery() == "query=test"); assert (uri11.getFragment() == "fragment"); }
bool OAuth2SessionLogin::handlePage(HTTP::WebContext &ctx, ostream &stream, const URI &uri) { HTTP::Connection &con = ctx.getConnection(); HTTP::Request &request = con.getRequest(); HTTP::Response &response = con.getResponse(); ctx.setDynamic(); // Don't cache // Force secure if (!con.isSecure()) THROWCS("Cannot logon via insecure port", HTTP::StatusCode::HTTP_UNAUTHORIZED); // Get session ID string sid = request.findCookie(sessionManager->getSessionCookie()); if (sid.empty() && uri.has("state")) sid = uri.get("state"); HTTP::SessionPtr session = sessionManager->findSession(ctx, sid); try { if (session.isNull() || (uri.has("state") && uri.get("state") != session->getID()) || (!uri.has("state") && session->getUser().empty())) { session = sessionManager->openSession(ctx); sid = session->getID(); URI redirectURL = auth->getRedirectURL(uri.getPath(), sid); response.redirect(redirectURL); } else if (session->getUser().empty()) { // TODO Make sure session is not very old URI postURI = auth->getVerifyURL(uri, sid); LOG_DEBUG(5, "Token URI: " << postURI); // Extract query data string data = postURI.getQuery(); postURI.setQuery(""); // Verify authorization with OAuth2 server HTTP::Transaction tran(sslCtx); tran.post(postURI, data.data(), data.length(), "application/x-www-form-urlencoded", 1.0); // Read response tran.receiveHeader(); JSON::ValuePtr token = JSON::Reader(tran).parse(); LOG_DEBUG(5, "Token Response: \n" << tran.getResponse() << *token); // Verify token string accessToken = auth->verifyToken(token); // Get profile URI profileURL = auth->getProfileURL(accessToken); HTTP::Transaction tran2(sslCtx); tran2.get(profileURL); // Read response tran2.receiveHeader(); JSON::ValuePtr profile = JSON::Reader(tran2).parse(); // Process profile string email = profile->getString("email"); if (!profile->getBoolean("email_verified")) THROWCS("Email not verified", HTTP::StatusCode::HTTP_UNAUTHORIZED); session->setUser(email); LOG_INFO(1, "Authorized: " << email); // Final redirect to remove auth parameters response.redirect(uri.getPath()); } else return false; // Already authorized // Make sure session cookie is set sessionManager->setSessionCookie(ctx); } catch (...) { // Close session on error if (!sid.empty()) sessionManager->closeSession(ctx, sid); throw; } return true; }