1
+ #include < util/string/join.h>
2
+
1
3
#include < ydb/core/tx/schemeshard/ut_helpers/helpers.h>
2
4
#include < ydb/library/login/login.h>
3
5
#include < ydb/core/protos/auth.pb.h>
@@ -6,15 +8,47 @@ using namespace NKikimr;
6
8
using namespace NSchemeShard ;
7
9
using namespace NSchemeShardUT_Private ;
8
10
11
+ namespace NSchemeShardUT_Private {
12
+
13
+ // convert into generic test helper?
14
+ void TestCreateAlterLoginCreateUser (TTestActorRuntime& runtime, ui64 txId, const TString& database, const TString& user, const TString& password, const TVector<TExpectedResult>& expectedResults) {
15
+ std::unique_ptr<TEvSchemeShard::TEvModifySchemeTransaction> modifyTx (CreateAlterLoginCreateUser (txId, user, password));
16
+ // TODO: move setting of TModifyScheme.WorkingDir into CreateAlterLoginCreateUser()
17
+ // NOTE: TModifyScheme.Name isn't set, intentionally
18
+ modifyTx->Record .MutableTransaction (0 )->SetWorkingDir (database);
19
+ AsyncSend (runtime, TTestTxConfig::SchemeShard, modifyTx.release ());
20
+ // AlterLoginCreateUser is synchronous in nature, result is returned immediately
21
+ TestModificationResults (runtime, txId, expectedResults);
22
+ }
23
+
24
+ } // namespace NSchemeShardUT_Private
25
+
26
+ namespace {
27
+
28
+ class TMemoryLogBackend : public TLogBackend {
29
+ public:
30
+ std::vector<std::string>& Buffer;
31
+
32
+ TMemoryLogBackend (std::vector<std::string>& buffer)
33
+ : Buffer(buffer)
34
+ {}
35
+
36
+ virtual void WriteData (const TLogRecord& rec) override {
37
+ Buffer.emplace_back (rec.Data , rec.Len );
38
+ }
39
+
40
+ virtual void ReopenLog () override {
41
+ }
42
+ };
43
+
44
+ } // anonymous namespace
45
+
9
46
Y_UNIT_TEST_SUITE (TSchemeShardLoginTest) {
10
47
Y_UNIT_TEST (BasicLogin) {
11
48
TTestBasicRuntime runtime;
12
49
TTestEnv env (runtime);
13
50
ui64 txId = 100 ;
14
- TActorId sender = runtime.AllocateEdgeActor ();
15
- std::unique_ptr<TEvSchemeShard::TEvModifySchemeTransaction> transaction (CreateAlterLoginCreateUser (++txId, " user1" , " password1" ));
16
- transaction->Record .MutableTransaction (0 )->SetWorkingDir (" /MyRoot" );
17
- ForwardToTablet (runtime, TTestTxConfig::SchemeShard, sender, transaction.release ());
51
+ TestCreateAlterLoginCreateUser (runtime, ++txId, " /MyRoot" , " user1" , " password1" , {{NKikimrScheme::StatusSuccess}});
18
52
auto resultLogin = Login (runtime, " user1" , " password1" );
19
53
UNIT_ASSERT_VALUES_EQUAL (resultLogin.error (), " " );
20
54
auto describe = DescribePath (runtime, TTestTxConfig::SchemeShard, " /MyRoot" );
@@ -35,10 +69,7 @@ Y_UNIT_TEST_SUITE(TSchemeShardLoginTest) {
35
69
TTestEnv env (runtime);
36
70
runtime.GetAppData ().AuthConfig .SetEnableLoginAuthentication (false );
37
71
ui64 txId = 100 ;
38
- TActorId sender = runtime.AllocateEdgeActor ();
39
- std::unique_ptr<TEvSchemeShard::TEvModifySchemeTransaction> transaction (CreateAlterLoginCreateUser (++txId, " user1" , " password1" ));
40
- transaction->Record .MutableTransaction (0 )->SetWorkingDir (" /MyRoot" );
41
- ForwardToTablet (runtime, TTestTxConfig::SchemeShard, sender, transaction.release ());
72
+ TestCreateAlterLoginCreateUser (runtime, ++txId, " /MyRoot" , " user1" , " password1" , {{NKikimrScheme::StatusPreconditionFailed}});
42
73
auto resultLogin = Login (runtime, " user1" , " password1" );
43
74
UNIT_ASSERT_VALUES_EQUAL (resultLogin.error (), " Login authentication is disabled" );
44
75
UNIT_ASSERT_VALUES_EQUAL (resultLogin.token (), " " );
@@ -48,4 +79,78 @@ Y_UNIT_TEST_SUITE(TSchemeShardLoginTest) {
48
79
UNIT_ASSERT (describe.GetPathDescription ().GetDomainDescription ().HasSecurityState ());
49
80
UNIT_ASSERT (describe.GetPathDescription ().GetDomainDescription ().GetSecurityState ().PublicKeysSize () > 0 );
50
81
}
82
+
83
+ NAudit::TAuditLogBackends CreateTestAuditLogBackends (std::vector<std::string>& buffer) {
84
+ NAudit::TAuditLogBackends logBackends;
85
+ logBackends[NKikimrConfig::TAuditConfig::TXT].emplace_back (new TMemoryLogBackend (buffer));
86
+ return logBackends;
87
+ }
88
+
89
+ Y_UNIT_TEST (AuditLogLoginSuccess) {
90
+ TTestBasicRuntime runtime;
91
+ std::vector<std::string> lines;
92
+ runtime.AuditLogBackends = std::move (CreateTestAuditLogBackends (lines));
93
+ TTestEnv env (runtime);
94
+
95
+ UNIT_ASSERT_VALUES_EQUAL (lines.size (), 1 ); // alter root subdomain
96
+
97
+ ui64 txId = 100 ;
98
+
99
+ TestCreateAlterLoginCreateUser (runtime, ++txId, " /MyRoot" , " user1" , " password1" , {{NKikimrScheme::StatusSuccess}});
100
+ UNIT_ASSERT_VALUES_EQUAL (lines.size (), 2 ); // +user creation
101
+
102
+ // test body
103
+ {
104
+ auto resultLogin = Login (runtime, " user1" , " password1" );
105
+ UNIT_ASSERT_C (resultLogin.error ().empty (), resultLogin);
106
+ }
107
+ UNIT_ASSERT_VALUES_EQUAL (lines.size (), 3 ); // +user login
108
+
109
+ Cerr << " auditlog lines:\n " << JoinSeq (' \n ' , lines) << Endl;
110
+ auto last = lines[lines.size () - 1 ];
111
+ Cerr << " auditlog last line:\n " << last << Endl;
112
+
113
+ UNIT_ASSERT_STRING_CONTAINS (last, " component=schemeshard" );
114
+ UNIT_ASSERT_STRING_CONTAINS (last, " remote_address=" ); // can't check the value
115
+ UNIT_ASSERT_STRING_CONTAINS (last, " database=/MyRoot" );
116
+ UNIT_ASSERT_STRING_CONTAINS (last, " operation=LOGIN" );
117
+ UNIT_ASSERT_STRING_CONTAINS (last, " status=SUCCESS" );
118
+ UNIT_ASSERT (!last.contains (" reason" ));
119
+ UNIT_ASSERT_STRING_CONTAINS (last, " login_user=user1" );
120
+ UNIT_ASSERT_STRING_CONTAINS (last, " login_auth_domain={none}" );
121
+ }
122
+
123
+ Y_UNIT_TEST (AuditLogLoginFailure) {
124
+ TTestBasicRuntime runtime;
125
+ std::vector<std::string> lines;
126
+ runtime.AuditLogBackends = std::move (CreateTestAuditLogBackends (lines));
127
+ TTestEnv env (runtime);
128
+
129
+ UNIT_ASSERT_VALUES_EQUAL (lines.size (), 1 ); // alter root subdomain
130
+
131
+ ui64 txId = 100 ;
132
+
133
+ TestCreateAlterLoginCreateUser (runtime, ++txId, " /MyRoot" , " user1" , " password1" , {{NKikimrScheme::StatusSuccess}});
134
+ UNIT_ASSERT_VALUES_EQUAL (lines.size (), 2 ); // +user creation
135
+
136
+ // test body
137
+ {
138
+ auto resultLogin = Login (runtime, " user1" , " bad_password" );
139
+ UNIT_ASSERT_C (!resultLogin.error ().empty (), resultLogin);
140
+ }
141
+ UNIT_ASSERT_VALUES_EQUAL (lines.size (), 3 ); // +user login
142
+
143
+ Cerr << " auditlog lines:\n " << JoinSeq (' \n ' , lines) << Endl;
144
+ auto last = lines[lines.size () - 1 ];
145
+ Cerr << " auditlog last line:\n " << last << Endl;
146
+
147
+ UNIT_ASSERT_STRING_CONTAINS (last, " component=schemeshard" );
148
+ UNIT_ASSERT_STRING_CONTAINS (last, " remote_address=" ); // can't check the value
149
+ UNIT_ASSERT_STRING_CONTAINS (last, " database=/MyRoot" );
150
+ UNIT_ASSERT_STRING_CONTAINS (last, " operation=LOGIN" );
151
+ UNIT_ASSERT_STRING_CONTAINS (last, " status=ERROR" );
152
+ UNIT_ASSERT_STRING_CONTAINS (last, " reason=Invalid password" );
153
+ UNIT_ASSERT_STRING_CONTAINS (last, " login_user=user1" );
154
+ UNIT_ASSERT_STRING_CONTAINS (last, " login_auth_domain={none}" );
155
+ }
51
156
}
0 commit comments