10Duke Scale C++ SDK
Loading...
Searching...
No Matches
OIDCSessionImpl_test.h
1#ifndef TENDUKE_TEST_OIDC_OIDCSESSIONIMPL_TEST_H
2#define TENDUKE_TEST_OIDC_OIDCSESSIONIMPL_TEST_H
3
4#include "oidc/session/OIDCSessionImpl.h"
5#include "oidc/session/DefaultOIDCSessionEventListener.h"
6#include "oauth/OAuthInvalidGrant.h"
7
8#include "mocks/ClockMock.h"
9#include "mocks/OIDCClientMock.h"
10#include "mocks/OIDCLoginMock.h"
11#include "mocks/OIDCLoginRequestMock.h"
12#include "mocks/OIDCRefreshRequestMock.h"
13
14#include "gmock/gmock.h"
15#include "gtest/gtest.h"
16
17#include <thread>
18
30
31using ::testing::_;
32using ::testing::Return;
33using ::testing::Throw;
34
35namespace tenduke { namespace test { namespace oidc {
36
38{
39public:
40 void loginStarting() override
41 {
43 loginStartingCalled++;
44 }
45
46 void loginComplete(const OIDCState &state) override
47 {
49 loginCompleteAccessTokens.emplace_back(state.getAccessToken());
50 }
51
52 void refreshComplete(const OIDCState &state) override
53 {
55 refreshCompleteAccessTokens.emplace_back(state.getAccessToken());
56 }
57
58 int loginStartingCalled = 0;
59 std::vector<std::string> loginCompleteAccessTokens;
60 std::vector<std::string> refreshCompleteAccessTokens;
61};
62
64{
65public:
66 void addAction(const std::string &action)
67 {
68 std::lock_guard<std::recursive_mutex> lock(mutex);
69 actions.emplace_back(action);
70 }
71
72 std::vector<std::string> getActions()
73 {
74 std::lock_guard<std::recursive_mutex> lock(mutex);
75 return actions;
76 }
77
78 std::vector<std::string> actions;
79private:
80 std::recursive_mutex mutex;
81};
82
83class FakeOIDCLoginRequest : public tenduke::oidc::OIDCLoginRequest
84{
85public:
86 explicit FakeOIDCLoginRequest(const std::chrono::milliseconds &sleepFor)
87 : sleepFor(sleepFor), abortCalled(0), recorder(nullptr)
88 {}
89 explicit FakeOIDCLoginRequest(const std::chrono::milliseconds &sleepFor, const std::shared_ptr<StateRecorder> &detector)
90 : sleepFor(sleepFor), abortCalled(0), recorder(detector)
91 {}
92
93 ~FakeOIDCLoginRequest() override
94 {
95 addAction("destroyed");
96 }
97
98 std::unique_ptr<::OIDCState> execute() override
99 {
100 addAction("execute-before-sleep");
101 std::this_thread::sleep_for(sleepFor);
102 addAction("execute-after-sleep");
103 return std::unique_ptr<::OIDCState>(new ::OIDCState("at", "rt", 200, false, {}, ::IdToken({}, {})));
104 }
105 void abort() override
106 {
107 addAction("abort");
108 abortCalled += 1;
109 }
110
111 void addAction(const std::string &action)
112 {
113 if (recorder != nullptr) recorder->addAction(action);
114 }
115
116 std::chrono::milliseconds sleepFor;
117 volatile std::uint64_t abortCalled;
118 std::shared_ptr<StateRecorder> recorder;
119};
120
121class OIDCSessionImplTest : public ::testing::Test
122{
123protected:
124 void SetUp() override
125 {
126 clock = ::ClockMock::createShared();
127 oidcLogin = ::OIDCLoginMock::createShared();
128 oidcClient = ::OIDCClientMock::createShared();
129 sessionEventListener = std::make_shared<SessionEventListener>();
130
131 EXPECT_CALL(*clock, epochSeconds()).WillRepeatedly(::Return(100));
132 }
133
134 std::shared_ptr<::ClockMock> clock;
135 std::shared_ptr<::OIDCLoginMock> oidcLogin;
136 std::shared_ptr<::OIDCClientMock> oidcClient;
137 std::shared_ptr<SessionEventListener> sessionEventListener;
138
139 // Helpers:
140 std::shared_ptr<::OIDCSessionImpl> session(
141 std::unique_ptr<::OIDCState> state,
142 std::uint64_t validitySafetyMarginS = 10,
143 std::chrono::milliseconds loginTimeout = std::chrono::milliseconds(0)
144 )
145 {
146 return std::make_shared<::OIDCSessionImpl>(
147 std::move(state),
148 oidcLogin,
149 oidcClient,
150 clock,
151 sessionEventListener,
152 validitySafetyMarginS,
153 loginTimeout
154 );
155 }
156 std::shared_ptr<::OIDCSessionImpl> session(
157 const ::OIDCState &state,
158 std::uint64_t validitySafetyMarginS = 10,
159 std::chrono::milliseconds loginTimeout = std::chrono::milliseconds(0)
160 )
161 {
162 return session(std::unique_ptr<::OIDCState>(new ::OIDCState(state)), validitySafetyMarginS, loginTimeout);
163 }
164 std::shared_ptr<::OIDCSessionImpl> session_without_state()
165 {
166 return session(nullptr);
167 }
168 std::shared_ptr<::OIDCSessionImpl> session_without_access_token()
169 {
170 return session(::OIDCState("", "", -1, false, {}, ::IdToken({}, {})));
171 }
172 std::shared_ptr<::OIDCSessionImpl> infinite_session(std::chrono::milliseconds loginTimeout = std::chrono::milliseconds (0))
173 {
174 return session(
175 ::OIDCState("at", "", ::TOKEN_DOES_NOT_EXPIRE, true, {}, ::IdToken({}, {})),
176 10,
177 loginTimeout
178 );
179 }
180 std::shared_ptr<::OIDCSessionImpl> session_that_expires_at(const std::int64_t expiresAt, const bool refreshable = true)
181 {
182 return session(::OIDCState("at", (refreshable ? "rt" : ""), expiresAt, false, {}, ::IdToken({}, {})));
183 }
184 ::OIDCState * createRefreshedState()
185 {
186 return new ::OIDCState(
187 "at-new",
188 "rt-new",
189 200,
190 false,
191 {},
192 ::IdToken({}, {})
193 );
194 }
195 void stubSuccessfulRefresh()
196 {
197 auto refreshRequest = new ::OIDCRefreshRequestMock();
198 auto refreshedState = createRefreshedState();
199
200 EXPECT_CALL(*oidcClient, refresh(::_)).WillOnce(::Return(std::unique_ptr<::OIDCRefreshRequestMock>(refreshRequest)));
201 EXPECT_CALL(*refreshRequest, execute()).WillOnce(::Return(std::unique_ptr<::OIDCState>(refreshedState)));
202 }
203 void stubOAuthInvalidGrantRefresh()
204 {
205 auto refreshRequest = new ::OIDCRefreshRequestMock();
206
207 EXPECT_CALL(*oidcClient, refresh(::_)).WillOnce(::Return(std::unique_ptr<::OIDCRefreshRequestMock>(refreshRequest)));
208 EXPECT_CALL(*refreshRequest, execute()).WillOnce(::Throw(::OAuthInvalidGrant(oauth::OAuthException::REFRESH_REQUEST, "", "")));
209 }
210 ::OIDCLoginRequestMock * stubLogin()
211 {
212 auto loginRequest = new ::OIDCLoginRequestMock();
213
214 EXPECT_CALL(*oidcLogin, login()).WillOnce(::Return(std::unique_ptr<::OIDCLoginRequestMock>(loginRequest)));
215 return loginRequest;
216 }
217
218 ::OIDCLoginRequestMock * stubSuccessfulLogin()
219 {
220 auto loginRequest = stubLogin();
221 auto state = createRefreshedState();
222
223 EXPECT_CALL(*loginRequest, execute()).WillOnce(::Return(std::unique_ptr<::OIDCState>(state)));
224
225 return loginRequest;
226 }
227};
228
229}}}
230
231#endif //TENDUKE_TEST_OIDC_OIDCSESSIONIMPL_TEST_H
void loginComplete(const ::tenduke::oidc::OIDCState &state) override
Called when OIDC login is complete.
Definition DefaultOIDCSessionEventListener.cpp:12
void loginStarting() override
Called when OIDCSession starts login.
Definition DefaultOIDCSessionEventListener.cpp:7
void refreshComplete(const ::tenduke::oidc::OIDCState &state) override
Called when OIDC session refresh is complete,.
Definition DefaultOIDCSessionEventListener.cpp:17
Exception thrown when server reported "invalid_grant".
Definition OAuthInvalidGrant.h:15
const std::string & getAccessToken() const override
Returns the access token.
Definition OAuthStateImpl.h:50
Default implementation of tenduke::oidc::OIDCSessionEventListener.
Definition DefaultOIDCSessionEventListener.h:14
OIDC ID-token.
Definition IdToken.h:15
Login-request initiated by OIDCLogin-service.
Definition OIDCLoginRequest.h:15
Default implementation of tenduke::oidc::OIDCSession.
Definition OIDCSessionImpl.h:23
Container of OIDC state, describing the user session.
Definition OIDCState.h:17
Definition ClockMock.h:13
Definition OIDCClientMock.h:11
Definition OIDCLoginMock.h:11
Definition OIDCLoginRequestMock.h:11
Definition OIDCRefreshRequestMock.h:11
std::unique_ptr<::OIDCState > execute() override
Performs the login.
Definition OIDCSessionImpl_test.h:98
void abort() override
Aborts the login.
Definition OIDCSessionImpl_test.h:105
Definition OIDCSessionImpl_test.h:122
Definition OIDCSessionImpl_test.h:38
void loginStarting() override
Called when OIDCSession starts login.
Definition OIDCSessionImpl_test.h:40
Definition OIDCSessionImpl_test.h:64
const std::int64_t TOKEN_DOES_NOT_EXPIRE
Magic value to denote that the access token does not expire.
Definition OAuthState.h:12
Root for classes, functions and globals of 10Duke C++ Client.
Definition AbstractClientFactory.h:16