1
1
#include < library/cpp/string_utils/base64/base64.h>
2
+ #include < library/cpp/string_utils/quote/quote.h>
2
3
#include < ydb/library/actors/http/http.h>
3
4
#include < ydb/library/security/util.h>
4
5
#include < ydb/mvp/core/mvp_log.h>
7
8
#include " oidc_session_create.h"
8
9
#include " oidc_impersonate_start_page_nebius.h"
9
10
10
- namespace NMVP {
11
- namespace NOIDC {
11
+ namespace NMVP ::NOIDC {
12
12
13
13
THandlerImpersonateStart::THandlerImpersonateStart (const NActors::TActorId& sender,
14
- const NHttp::THttpIncomingRequestPtr& request,
15
- const NActors::TActorId& httpProxyId,
16
- const TOpenIdConnectSettings& settings)
14
+ const NHttp::THttpIncomingRequestPtr& request,
15
+ const NActors::TActorId& httpProxyId,
16
+ const TOpenIdConnectSettings& settings)
17
17
: Sender(sender)
18
18
, Request(request)
19
19
, HttpProxyId(httpProxyId)
20
20
, Settings(settings)
21
21
{}
22
22
23
23
void THandlerImpersonateStart::Bootstrap (const NActors::TActorContext& ctx) {
24
- LOG_DEBUG_S (ctx, EService::MVP, " Start impersonation process" );
24
+ BLOG_D (" Start impersonation process" );
25
+
25
26
NHttp::TUrlParameters urlParameters (Request->URL );
26
27
TString serviceAccountId = urlParameters[" service_account_id" ];
27
28
@@ -31,32 +32,26 @@ void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) {
31
32
TString sessionCookieName = CreateNameSessionCookie (Settings.ClientId );
32
33
TStringBuf sessionCookieValue = cookies.Get (sessionCookieName);
33
34
if (!sessionCookieValue.Empty ()) {
34
- LOG_DEBUG_S (ctx, EService::MVP, " Using session cookie (" << sessionCookieName << " : " << NKikimr::MaskTicket (sessionCookieValue) << " )" );
35
+ BLOG_D ( " Using session cookie (" << sessionCookieName << " : " << NKikimr::MaskTicket (sessionCookieValue) << " )" );
35
36
}
37
+ TString sessionToken = DecodeToken (sessionCookieValue);
38
+ TStringBuf impersonatedCookieValue = GetCookie (cookies, CreateNameImpersonatedCookie (Settings.ClientId ));
36
39
37
- TString sessionToken = DecodeToken (sessionCookieValue, ctx);
38
-
39
- TString jsonError;
40
40
if (sessionToken.empty ()) {
41
- jsonError = " Wrong impersonate parameter: session cookie not found" ;
42
- } else if (serviceAccountId.empty ()) {
43
- jsonError = " Wrong impersonate parameter: account_id not found" ;
41
+ return ReplyBadRequestAndDie (" Wrong impersonate parameter: session cookie not found" , ctx);
44
42
}
45
-
46
- if (jsonError) {
47
- NHttp::THeadersBuilder responseHeaders;
48
- responseHeaders.Set (" Content-Type" , " text/plain" );
49
- SetCORS (Request, &responseHeaders);
50
- NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse (" 400" , " Bad Request" , responseHeaders, jsonError);
51
- ctx.Send (Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse (httpResponse));
52
- Die (ctx);
53
- } else {
54
- RequestImpersonatedToken (sessionToken, serviceAccountId, ctx);
43
+ if (!impersonatedCookieValue.empty ()) {
44
+ return ReplyBadRequestAndDie (" Wrong impersonate parameter: impersonated cookie already exists" , ctx);
55
45
}
46
+ if (serviceAccountId.empty ()) {
47
+ return ReplyBadRequestAndDie (" Wrong impersonate parameter: service_account_id not found" , ctx);
48
+ }
49
+
50
+ RequestImpersonatedToken (sessionToken, serviceAccountId, ctx);
56
51
}
57
52
58
53
void THandlerImpersonateStart::RequestImpersonatedToken (const TString& sessionToken, const TString& serviceAccountId, const NActors::TActorContext& ctx) {
59
- LOG_DEBUG_S (ctx, EService::MVP, " Request impersonated token" );
54
+ BLOG_D ( " Request impersonated token" );
60
55
NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost (Settings.GetImpersonateEndpointURL ());
61
56
httpRequest->Set <&NHttp::THttpRequest::ContentType>(" application/x-www-form-urlencoded" );
62
57
@@ -70,7 +65,9 @@ void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionTo
70
65
TStringBuilder body;
71
66
body << " session=" << sessionToken
72
67
<< " &service_account_id=" << serviceAccountId;
73
- httpRequest->Set <&NHttp::THttpRequest::Body>(body);
68
+ TString bodyStr = body;
69
+ CGIEscape (bodyStr);
70
+ httpRequest->Set <&NHttp::THttpRequest::Body>(bodyStr);
74
71
75
72
ctx.Send (HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest (httpRequest));
76
73
Become (&THandlerImpersonateStart::StateWork);
@@ -79,24 +76,22 @@ void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionTo
79
76
void THandlerImpersonateStart::ProcessImpersonatedToken (const TString& impersonatedToken, const NActors::TActorContext& ctx) {
80
77
TString impersonatedCookieName = CreateNameImpersonatedCookie (Settings.ClientId );
81
78
TString impersonatedCookieValue = Base64Encode (impersonatedToken);
82
- LOG_DEBUG_S (ctx, EService::MVP, " Set impersonated cookie: (" << impersonatedCookieName << " : " << NKikimr::MaskTicket (impersonatedCookieValue) << " )" );
79
+ BLOG_D ( " Set impersonated cookie: (" << impersonatedCookieName << " : " << NKikimr::MaskTicket (impersonatedCookieValue) << " )" );
83
80
84
81
NHttp::THeadersBuilder responseHeaders;
85
82
responseHeaders.Set (" Set-Cookie" , CreateSecureCookie (impersonatedCookieName, impersonatedCookieValue));
86
83
SetCORS (Request, &responseHeaders);
87
- NHttp::THttpOutgoingResponsePtr httpResponse;
88
- httpResponse = Request->CreateResponse (" 200" , " OK" , responseHeaders);
89
- ctx.Send (Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse (httpResponse));
90
- Die (ctx);
84
+ NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse (" 200" , " OK" , responseHeaders);
85
+ ReplyAndDie (httpResponse, ctx);
91
86
}
92
87
93
88
void THandlerImpersonateStart::Handle (NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
94
89
NHttp::THttpOutgoingResponsePtr httpResponse;
95
90
if (event->Get ()->Error .empty () && event->Get ()->Response ) {
96
91
NHttp::THttpIncomingResponsePtr response = event->Get ()->Response ;
97
- LOG_DEBUG_S (ctx, EService::MVP, " Incoming response from authorization server: " << response->Status );
92
+ BLOG_D ( " Incoming response from authorization server: " << response->Status );
98
93
if (response->Status == " 200" ) {
99
- TStringBuf jsonError ;
94
+ TStringBuf errorMessage ;
100
95
NJson::TJsonValue jsonValue;
101
96
NJson::TJsonReaderConfig jsonConfig;
102
97
if (NJson::ReadJsonTree (response->Body , &jsonConfig, &jsonValue)) {
@@ -106,34 +101,45 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon
106
101
ProcessImpersonatedToken (impersonatedToken, ctx);
107
102
return ;
108
103
} else {
109
- jsonError = " Wrong OIDC provider response: impersonated token not found" ;
104
+ errorMessage = " Wrong OIDC provider response: impersonated token not found" ;
110
105
}
111
106
} else {
112
- jsonError = " Wrong OIDC response" ;
107
+ errorMessage = " Wrong OIDC response" ;
113
108
}
114
109
NHttp::THeadersBuilder responseHeaders;
115
110
responseHeaders.Set (" Content-Type" , " text/plain" );
116
111
SetCORS (Request, &responseHeaders);
117
- httpResponse = Request->CreateResponse (" 400" , " Bad Request" , responseHeaders, jsonError );
112
+ return ReplyAndDie ( Request->CreateResponse (" 400" , " Bad Request" , responseHeaders, errorMessage), ctx );
118
113
} else {
119
114
NHttp::THeadersBuilder responseHeaders;
120
115
NHttp::THeaders headers (response->Headers );
121
116
if (headers.Has (" Content-Type" )) {
122
117
responseHeaders.Set (" Content-Type" , headers.Get (" Content-Type" ));
123
118
}
124
119
SetCORS (Request, &responseHeaders);
125
- httpResponse = Request->CreateResponse (response->Status , response->Message , responseHeaders, response->Body );
120
+ return ReplyAndDie ( Request->CreateResponse (response->Status , response->Message , responseHeaders, response->Body ), ctx );
126
121
}
127
122
} else {
128
123
NHttp::THeadersBuilder responseHeaders;
129
124
responseHeaders.Set (" Content-Type" , " text/plain" );
130
125
SetCORS (Request, &responseHeaders);
131
- httpResponse = Request->CreateResponse (" 400" , " Bad Request" , responseHeaders, event->Get ()->Error );
126
+ return ReplyAndDie ( Request->CreateResponse (" 400" , " Bad Request" , responseHeaders, event->Get ()->Error ), ctx );
132
127
}
128
+ }
129
+
130
+ void THandlerImpersonateStart::ReplyAndDie (NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) {
133
131
ctx.Send (Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse (httpResponse));
134
132
Die (ctx);
135
133
}
136
134
135
+ void THandlerImpersonateStart::ReplyBadRequestAndDie (const TString& errorMessage, const NActors::TActorContext& ctx) {
136
+ NHttp::THeadersBuilder responseHeaders;
137
+ responseHeaders.Set (" Content-Type" , " text/plain" );
138
+ SetCORS (Request, &responseHeaders);
139
+ NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse (" 400" , " Bad Request" , responseHeaders, errorMessage);
140
+ ReplyAndDie (httpResponse, ctx);
141
+ }
142
+
137
143
TImpersonateStartPageHandler::TImpersonateStartPageHandler (const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings)
138
144
: TBase(&TImpersonateStartPageHandler::StateWork)
139
145
, HttpProxyId(httpProxyId)
@@ -144,5 +150,4 @@ void TImpersonateStartPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRe
144
150
ctx.Register (new THandlerImpersonateStart (event->Sender , event->Get ()->Request , HttpProxyId, Settings));
145
151
}
146
152
147
- } // NOIDC
148
- } // NMVP
153
+ } // NMVP::NOIDC
0 commit comments