| 590 | } |
| 591 | |
| 592 | bool HttpServer::isWebSocketAuthorized(const std::string& resource) { |
| 593 | if (!_authRequired) { |
| 594 | return true; |
| 595 | } |
| 596 | if (_authToken.empty()) { |
| 597 | return false; |
| 598 | } |
| 599 | if (_authTokenHasExpiry && std::chrono::steady_clock::now() > _authTokenExpiry) { |
| 600 | _authToken.clear(); |
| 601 | _authSessionId.clear(); |
| 602 | _authSessionSecret.clear(); |
| 603 | _authTokenHasExpiry = false; |
| 604 | return false; |
| 605 | } |
| 606 | if (_authSessionId.empty()) { |
| 607 | auto token = get_query_param(resource, "auth"s); |
| 608 | return isTokenValid(token); |
| 609 | } |
| 610 | auto params = parse_query_pairs(resource); |
| 611 | std::string sessionId; |
| 612 | std::string timestamp; |
| 613 | std::string nonce; |
| 614 | std::string signature; |
| 615 | std::vector<std::pair<std::string, std::string>> signParams; |
| 616 | signParams.reserve(params.size()); |
| 617 | for (const auto& param : params) { |
| 618 | if (param.first == "session"s) { |
| 619 | sessionId = param.second; |
| 620 | } else if (param.first == "ts"s) { |
| 621 | timestamp = param.second; |
| 622 | } else if (param.first == "nonce"s) { |
| 623 | nonce = param.second; |
| 624 | } else if (param.first == "sig"s) { |
| 625 | signature = param.second; |
| 626 | } else { |
| 627 | signParams.push_back(param); |
| 628 | } |
| 629 | } |
| 630 | if (sessionId.empty() || timestamp.empty() || nonce.empty() || signature.empty()) { |
| 631 | return false; |
| 632 | } |
| 633 | if (sessionId != _authSessionId) { |
| 634 | return false; |
| 635 | } |
| 636 | long long tsValue = 0; |
| 637 | try { |
| 638 | tsValue = std::stoll(timestamp); |
| 639 | } catch (...) { |
| 640 | return false; |
| 641 | } |
| 642 | auto now = std::chrono::system_clock::now(); |
| 643 | auto nowSeconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count(); |
| 644 | if (std::llabs(nowSeconds - tsValue) > AuthSignatureTTLSeconds) { |
| 645 | return false; |
| 646 | } |
| 647 | auto pathEnd = resource.find('?'); |
| 648 | auto path = pathEnd == std::string::npos ? resource : resource.substr(0, pathEnd); |
| 649 | signParams.emplace_back("nonce"s, nonce); |
no test coverage detected