Skip to content

Commit b9191b6

Browse files
authored
feat(login): create new sql login (#96)
* feat(login): create new sql login * feat(tests): integration * fix(tests): review * fix(test-dispose): review
1 parent ad13f56 commit b9191b6

6 files changed

Lines changed: 121 additions & 3 deletions

File tree

src/AgDatabase.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ namespace AgDatabaseMove
1212
using System.Data.SqlClient;
1313
using System.Linq;
1414
using System.Threading;
15+
using System.Threading.Tasks;
1516
using Exceptions;
17+
using Microsoft.SqlServer.Management.Smo;
1618
using Polly;
1719
using SmoFacade;
20+
using AvailabilityGroup = SmoFacade.AvailabilityGroup;
21+
using Server = SmoFacade.Server;
1822

1923

2024
public interface IAgDatabase
@@ -158,7 +162,19 @@ public void DropAllLogins()
158162

159163
public void AddLogin(LoginProperties login)
160164
{
161-
_listener.ForEachAgInstance(server => server.AddLogin(login));
165+
if (login.LoginType == LoginType.SqlLogin && login.Sid == null) {
166+
AddNewSqlLogin(login);
167+
}
168+
else {
169+
_listener.ForEachAgInstance(server => server.AddLogin(login));
170+
}
171+
}
172+
173+
private void AddNewSqlLogin(LoginProperties login)
174+
{
175+
var createdLogin = _listener.Primary.AddLogin(login);
176+
login.Sid = createdLogin.Sid;
177+
Parallel.ForEach(_listener.Secondaries, server => server.AddLogin(login));
162178
}
163179

164180
public IEnumerable<RoleProperties> AssociatedRoles()

src/SmoFacade/Login.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ private static Microsoft.SqlServer.Management.Smo.Login ConstructLogin(LoginProp
123123
else {
124124
login.Create();
125125
}
126+
login.Refresh();
126127

127128
return login;
128129
}

src/SmoFacade/Server.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@ private void Backup(Backup backup, string backupDirectoryPathQuery, string datab
278278
backup.SqlBackup(_server);
279279
}
280280

281-
public void AddLogin(LoginProperties login)
281+
public Login AddLogin(LoginProperties login)
282282
{
283283
var matchingLogin =
284284
Logins.SingleOrDefault(l => l.Name.Equals(login.Name, StringComparison.InvariantCultureIgnoreCase));
285-
if(matchingLogin == null) matchingLogin = new Login(login, this);
285+
return matchingLogin ?? new Login(login, this);
286286
}
287287

288288
public void AddRole(LoginProperties login, RoleProperties role)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace AgDatabaseMove.Integration.Config
2+
{
3+
public class TestAgDatabaseConfig
4+
{
5+
public string ConnectionString { get; set; }
6+
public string DatabaseName { get; set; }
7+
public string BackUpPathSqlQuery { get; set; }
8+
public string CredentialName { get; set; }
9+
}
10+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
namespace AgDatabaseMove.Integration.Fixtures
2+
{
3+
using Config;
4+
using System;
5+
using System.Collections.Generic;
6+
using Microsoft.SqlServer.Management.Smo;
7+
using SmoFacade;
8+
using System.Linq;
9+
10+
public class TestAgDatabaseFixture : IDisposable
11+
{
12+
public readonly TestAgDatabaseConfig _agConfig =
13+
new TestConfiguration<TestAgDatabaseConfig>("TestAgDatabase")._config;
14+
15+
public readonly TestLoginConfig _loginConfig =
16+
new TestConfiguration<TestLoginConfig>("TestLogin")._config;
17+
18+
public AgDatabase _agDatabase;
19+
20+
public IEnumerable<SmoFacade.Login> _createdLogins;
21+
22+
public TestAgDatabaseFixture()
23+
{
24+
_agDatabase = new AgDatabase(new DatabaseConfig
25+
{
26+
BackupPathSqlQuery = _agConfig.BackUpPathSqlQuery,
27+
ConnectionString = _agConfig.ConnectionString,
28+
DatabaseName = _agConfig.DatabaseName,
29+
CredentialName = _agConfig.CredentialName
30+
});
31+
_agDatabase.AddLogin(new LoginProperties
32+
{
33+
Name = _loginConfig.LoginName,
34+
Password = _loginConfig.Password,
35+
LoginType = LoginType.SqlLogin,
36+
DefaultDatabase = _loginConfig.DefaultDatabase
37+
});
38+
39+
_createdLogins = GetCreatedLogins();
40+
}
41+
42+
private IEnumerable<SmoFacade.Login> GetCreatedLogins()
43+
{
44+
List<SmoFacade.Login> logins = new List<SmoFacade.Login>();
45+
logins.Add(_agDatabase._listener.Primary.Logins
46+
.SingleOrDefault(l => l.Name.Equals(_loginConfig.LoginName, StringComparison.InvariantCultureIgnoreCase)));
47+
foreach (var server in _agDatabase._listener.Secondaries)
48+
{
49+
logins.Add(server.Logins
50+
.SingleOrDefault(l => l.Name.Equals(_loginConfig.LoginName, StringComparison.InvariantCultureIgnoreCase)));
51+
}
52+
53+
return logins;
54+
}
55+
56+
public void Dispose()
57+
{
58+
_agDatabase?.DropLogin(new LoginProperties { Name = _loginConfig.LoginName });
59+
_agDatabase?.Dispose();
60+
}
61+
}
62+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace AgDatabaseMove.Integration
2+
{
3+
using System.Linq;
4+
using Xunit;
5+
using Fixtures;
6+
7+
public class TestAgDatabase : IClassFixture<TestAgDatabaseFixture>
8+
{
9+
private readonly TestAgDatabaseFixture _fixture;
10+
11+
public TestAgDatabase(TestAgDatabaseFixture testAgDatabaseFixture)
12+
{
13+
_fixture = testAgDatabaseFixture;
14+
}
15+
16+
[Fact]
17+
public void TestLoginsExist()
18+
{
19+
_fixture._agDatabase.ContainsLogin(_fixture._loginConfig.LoginName);
20+
}
21+
22+
[Fact]
23+
public void TestLoginSidsMatch()
24+
{
25+
var sid = _fixture._createdLogins.First().Sid;
26+
Assert.All(_fixture._createdLogins.Select(l => l.Sid), s => Assert.Equal(s, sid));
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)