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;
}
Exemple #2
0
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;
}