summaryrefslogtreecommitdiffstats
path: root/ydb/mvp/oidc_proxy/extension_manager.cpp
blob: 33db197a4bd886017205750196f28f96df77a519 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "extension_manager.h"

#include "extension_final.h"
#include "extension_whoami.h"

namespace NMVP::NOIDC {

TExtensionManager::TExtensionManager(const TActorId sender,
                                     const TOpenIdConnectSettings& settings,
                                     const TCrackedPage& protectedPage,
                                     const TString authHeader)
    : Settings(settings)
    , AuthHeader(std::move(authHeader))
{
    ExtensionCtx = MakeIntrusive<TExtensionContext>();
    ExtensionCtx->Params = MakeHolder<TProxiedResponseParams>();
    ExtensionCtx->Params->ProtectedPage = MakeHolder<TCrackedPage>(protectedPage);
    ExtensionCtx->Sender = sender;
}

void TExtensionManager::SetRequest(NHttp::THttpIncomingRequestPtr request) {
    ExtensionCtx->Params->Request = std::move(request);
}

void TExtensionManager::SetOverrideResponse(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) {
    ExtensionCtx->Params->HeadersOverride = MakeHolder<NHttp::THeadersBuilder>();
    if (!event) {
        ExtensionCtx->Params->ResponseError = "Timeout while waiting for whoami info";
    } else if (!event->Get()->Response) {
        ExtensionCtx->Params->ResponseError = event->Get()->GetError();
    } else {
        auto& response = event->Get()->Response;
        ExtensionCtx->Params->StatusOverride = response->Status;
        auto headers = NHttp::THeaders(response->Headers);
        for (const auto& header : headers.Headers) {
            ExtensionCtx->Params->HeadersOverride->Set(header.first, header.second);
        }
        ExtensionCtx->Params->MessageOverride = response->Message;
        ExtensionCtx->Params->BodyOverride = response->Body;
    }
}

void TExtensionManager::AddExtensionWhoami() {
    EnrichmentExtension = true;
    AddExtension(NActors::TActivationContext::ActorSystem()->Register(new TExtensionWhoami(Settings, AuthHeader)));
}

void TExtensionManager::AddExtensionFinal() {
    AddExtension(NActors::TActivationContext::ActorSystem()->Register(new TExtensionFinal(Settings)));
}

void TExtensionManager::AddExtension(const NActors::TActorId& stage) {
    ExtensionCtx->Route.push(stage);
}

bool TExtensionManager::NeedExtensionWhoami(const NHttp::THttpIncomingRequestPtr& request) const {
    if (Settings.AccessServiceType == NMvp::yandex_v2) {
        return false; // does not support whoami extension
    }

    if (request->Method == "OPTIONS" || Settings.WhoamiExtendedInfoEndpoint.empty()) {
        return false;
    }

    TCrackedPage page(request);
    auto path = TStringBuf(page.Url).Before('?');

    static constexpr TStringBuf WHOAMI_PATHS[] = { "/viewer/json/whoami", "/viewer/whoami" };
    for (const auto& whoamiPath : WHOAMI_PATHS) {
        if (path.EndsWith(whoamiPath)) {
            return true;
        }
    }
    return false;
}

void TExtensionManager::ArrangeExtensions(const NHttp::THttpIncomingRequestPtr& request) {
    if (NeedExtensionWhoami(request)) {
        AddExtensionWhoami();
    }
    AddExtensionFinal();
}

bool TExtensionManager::HasEnrichmentExtension() {
    return EnrichmentExtension;
}

void TExtensionManager::StartExtensionProcess(NHttp::THttpIncomingRequestPtr request,
                                              NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) {
    SetRequest(std::move(request));
    SetOverrideResponse(std::move(event));

    const auto route = ExtensionCtx->Route.Next();
    NActors::TActivationContext::ActorSystem()->Send(route, new TEvPrivate::TEvExtensionRequest(std::move(ExtensionCtx)));
}

} // NMVP::NOIDC