void WRestResource::handleRequest(const Http::Request &request, Http::Response &response) { try { auto it = std::find(METHOD_STRINGS.cbegin(), METHOD_STRINGS.cend(), request.method()); auto idx = static_cast<std::size_t>(std::distance(METHOD_STRINGS.cbegin(), it)); if (it == METHOD_STRINGS.cend() || !handlers_[idx]) response.setStatus(405); } catch (Exception e) { response.setStatus(e.status()); } }
void WebSocketFramer::acceptRequest(http::Request& request, http::Response& response) { if (util::icompare(request.get("Connection", ""), "upgrade") == 0 && util::icompare(request.get("Upgrade", ""), "websocket") == 0) { std::string version = request.get("Sec-WebSocket-Version", ""); if (version.empty()) throw std::runtime_error("WebSocket error: Missing Sec-WebSocket-Version in handshake request"); //, ws::ErrorHandshakeNoVersion if (version != ws::ProtocolVersion) throw std::runtime_error("WebSocket error: Unsupported WebSocket version requested: " + version); //, ws::ErrorHandshakeUnsupportedVersion std::string key = util::trim(request.get("Sec-WebSocket-Key", "")); if (key.empty()) throw std::runtime_error("WebSocket error: Missing Sec-WebSocket-Key in handshake request"); //, ws::ErrorHandshakeNoKey response.setStatus(http::StatusCode::SwitchingProtocols); response.set("Upgrade", "websocket"); response.set("Connection", "Upgrade"); response.set("Sec-WebSocket-Accept", computeAccept(key)); // Set headerState 2 since the handshake was accepted. _headerState = 2; } else throw std::runtime_error("WebSocket error: No WebSocket handshake"); //, ws::ErrorNoHandshake }
void OAuthTokenEndpoint::handleRequest(const Http::Request &request, Http::Response &response) { #ifdef WT_TARGET_JAVA try { #endif // WT_TARGET_JAVA response.setMimeType("application/json"); response.addHeader("Cache-Control", "no-store"); response.addHeader("Pragma", "no-cache"); const std::string *grantType = request.getParameter("grant_type"); const std::string *redirectUri = request.getParameter("redirect_uri"); const std::string *code = request.getParameter("code"); std::string clientId; std::string clientSecret; ClientSecretMethod authMethod = HttpAuthorizationBasic; // Preferred method: get authorization information from // Http Basic authentication std::string headerSecret; std::string authHeader = request.headerValue("Authorization"); if (authHeader.length() > AUTH_TYPE.length() + 1) { #ifndef WT_TARGET_JAVA headerSecret = Utils::base64Decode(authHeader.substr(AUTH_TYPE.length() + 1)); #else headerSecret = Utils::base64DecodeS(authHeader.substr(AUTH_TYPE.length() + 1)); #endif // WT_TARGET_JAVA std::vector<std::string> tokens; boost::split(tokens, headerSecret, boost::is_any_of(":")); if (tokens.size() == 2) { clientId = Utils::urlDecode(tokens[0]); clientSecret = Utils::urlDecode(tokens[1]); authMethod = HttpAuthorizationBasic; } } // Alternative method: pass authorization information as parameters // (only allowed for post methods) if (clientId.empty() && clientSecret.empty()) { const std::string *clientIdParam = request.getParameter("client_id"); const std::string *clientSecretParam = request.getParameter("client_secret"); if (clientIdParam && clientSecretParam) { clientId = *clientIdParam; clientSecret = *clientSecretParam; authMethod = RequestBodyParameter; } } if (!code || clientId.empty() || clientSecret.empty() || !grantType || !redirectUri) { response.setStatus(400); response.out() << "{\"error\": \"invalid_request\"}" << std::endl; return; } OAuthClient client = db_->idpClientFindWithId(clientId); if (!client.checkValid() || !client.verifySecret(clientSecret) || client.authMethod() != authMethod) { response.setStatus(401); if (!authHeader.empty()) { if (client.authMethod() == HttpAuthorizationBasic) response.addHeader("WWW-Authenticate", AUTH_TYPE); else response.addHeader("WWW-Authenticate", methodToString(client.authMethod())); } response.out() << "{\n\"error\": \"invalid_client\"\n}" << std::endl; return; } if (*grantType != GRANT_TYPE) { response.setStatus(400); response.out() << "{\n\"error\": \"unsupported_grant_type\"\n}" << std::endl; return; } IssuedToken authCode = db_->idpTokenFindWithValue(GRANT_TYPE, *code); if (!authCode.checkValid() || authCode.redirectUri() != *redirectUri || WDateTime::currentDateTime() > authCode.expirationTime()) { response.setStatus(400); response.out() << "{\n\"error\": \"invalid_grant\"\n}" << std::endl; return; } std::string accessTokenValue = WRandom::generateId(); WDateTime expirationTime = WDateTime::currentDateTime().addSecs(accessExpSecs_); const User &user = authCode.user(); const OAuthClient &authClient = authCode.authClient(); const std::string scope = authCode.scope(); db_->idpTokenAdd(accessTokenValue, expirationTime, "access_token", scope, authCode.redirectUri(), user, authClient); db_->idpTokenRemove(authCode); response.setStatus(200); Json::Object root; root["access_token"] = Json::Value(accessTokenValue); root["token_type"] = Json::Value("Bearer"); root["expires_in"] = Json::Value(accessExpSecs_); if (authCode.scope().find("openid") != std::string::npos) { std::string header; std::string signature; std::string payload = Utils::base64Encode(idTokenPayload(authClient.clientId(), scope, user), false); #ifndef WT_TARGET_JAVA #ifdef WT_WITH_SSL if (privateKey) { header = Utils::base64Encode("{\n\"typ\": \"JWT\",\n\"alg\": \"RS256\"\n}", false); signature = Utils::base64Encode(rs256(header + "." + payload), false); } else { #endif // WT_WITH_SSL #endif // WT_TARGET_JAVA header = Utils::base64Encode("{\n\"typ\": \"JWT\",\n\"alg\": \"none\"\n}", false); signature = Utils::base64Encode("", false); #ifndef WT_TARGET_JAVA #ifdef WT_WITH_SSL } #endif // WT_WITH_SSL #endif // WT_TARGET_JAVA root["id_token"] = Json::Value(header + "." + payload + "." + signature); } response.out() << Json::serialize(root); #ifdef WT_TARGET_JAVA } catch (std::io_exception ioe) { LOG_ERROR(ioe.message()); } #endif }