feat: add user management, refs NOISSUE
This commit is contained in:
@@ -5,11 +5,17 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using System.DirectoryServices.Protocols;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
SignalIntegration.Instance = new SignalIntegration(AppConfiguration.Instance.SignalAPIEndpointUri,
|
||||
int.Parse(AppConfiguration.Instance.SignalAPIEndpointPort),
|
||||
AppConfiguration.Instance.HostPhoneNumber);
|
||||
|
||||
LdapIntegration.Instance = new LdapIntegration(AppConfiguration.Instance.LDAPConfig.LDAPserver,
|
||||
AppConfiguration.Instance.LDAPConfig.Port,
|
||||
AppConfiguration.Instance.LDAPConfig.Username,
|
||||
AppConfiguration.Instance.LDAPConfig.Password);
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
Console.WriteLine("Setting up user check timer");
|
||||
@@ -34,7 +40,9 @@ userCheckTimer.OnOccurence += async (s, ea) =>
|
||||
Name = newUserContact.Name,
|
||||
SignalMemberId = memberId,
|
||||
NickName = string.Empty,
|
||||
IsIntroduced = false
|
||||
IsIntroduced = false,
|
||||
LdapUserName = string.Empty,
|
||||
AssociationInProgress = false,
|
||||
};
|
||||
dci.Users.Add(newUser);
|
||||
needsSaving = true;
|
||||
@@ -47,7 +55,7 @@ userCheckTimer.OnOccurence += async (s, ea) =>
|
||||
}
|
||||
await dci.DisposeAsync();
|
||||
};
|
||||
//userCheckTimer.Start();
|
||||
userCheckTimer.Start();
|
||||
|
||||
Console.WriteLine("Setting up user intro timer");
|
||||
var userIntroTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false);
|
||||
@@ -69,13 +77,23 @@ userIntroTimer.OnOccurence += async (s, ea) =>
|
||||
}
|
||||
await dci.DisposeAsync();
|
||||
};
|
||||
//userIntroTimer.Start();
|
||||
userIntroTimer.Start();
|
||||
|
||||
|
||||
Console.WriteLine("Setting up pick of the day timer");
|
||||
var pickOfTheDayTimer = new CronTimer("0 8 * * *", "Europe/Vienna", includingSeconds: false);
|
||||
pickOfTheDayTimer.OnOccurence += async (s, ea) =>
|
||||
{
|
||||
var rand = new Random();
|
||||
var num = rand.NextInt64();
|
||||
var mod = num % AppConfiguration.Instance.AverageDaysBetweenRequests;
|
||||
|
||||
if (mod > 0)
|
||||
{
|
||||
Console.WriteLine("Skipping pick of the day today!");
|
||||
return;
|
||||
}
|
||||
|
||||
var dci = DataContext.Instance;
|
||||
var luckyUser = await dci.Users.ElementAtAsync((new Random()).Next(await dci.Users.CountAsync()));
|
||||
var userName = string.IsNullOrEmpty(luckyUser.NickName) ? luckyUser.Name : luckyUser.NickName;
|
||||
@@ -85,88 +103,57 @@ pickOfTheDayTimer.OnOccurence += async (s, ea) =>
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"Today's (optional) suggestion helper to help you pick a song is:\n\n**{suggestion.Title}**\n\n*{suggestion.Description}*", luckyUser.SignalMemberId);
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"For now please just share your suggestion with the group - in the future I might ask you to share directly with me or via the website to help me keep track of past suggestions!", luckyUser.SignalMemberId);
|
||||
};
|
||||
//pickOfTheDayTimer.Start();
|
||||
pickOfTheDayTimer.Start();
|
||||
|
||||
var connection = new LdapConnection(AppConfiguration.Instance.LDAPConfig.LDAPserver)
|
||||
var startUserAssociationProcess = (User userToAssociate) =>
|
||||
{
|
||||
Credential = new(
|
||||
AppConfiguration.Instance.LDAPConfig.Username,
|
||||
AppConfiguration.Instance.LDAPConfig.Password
|
||||
)
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"Hi, I see you are not associated with any website user yet.", userToAssociate.SignalMemberId);
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"If you haven't yet, please navigate to https://users.disi.dev to create a new account.", userToAssociate.SignalMemberId);
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"Once you have done so, go to https://sotd.disi.dev, login, navigate to \"Unclaimed Phone Numbers\" and click on the \"Claim\" button to start the claim process.", userToAssociate.SignalMemberId);
|
||||
SignalIntegration.Instance.SendMessageToUserAsync($"With a future update you will be required to submit songs via your user account - at that point you will be skipped during the selection process if you have not yet claimed your phone number!", userToAssociate.SignalMemberId);
|
||||
};
|
||||
|
||||
var attributesToQuery = new string[]
|
||||
Console.WriteLine("Setting up LdapAssociation timer");
|
||||
var ldapAssociationTimer = new CronTimer("*/10 * * * *", "Europe/Vienna", includingSeconds: false);
|
||||
ldapAssociationTimer.OnOccurence += async (s, ea) =>
|
||||
{
|
||||
"objectGUID",
|
||||
"sAMAccountName",
|
||||
"displayName",
|
||||
"mail",
|
||||
"whenCreated"
|
||||
};
|
||||
|
||||
SearchResponse SearchInAD(
|
||||
string ldapServer,
|
||||
int ldapPort,
|
||||
string domainForAD,
|
||||
string username,
|
||||
string password,
|
||||
string targetOU,
|
||||
string query,
|
||||
SearchScope scope,
|
||||
params string[] attributeList
|
||||
)
|
||||
{
|
||||
// on Windows the authentication type is Negotiate, so there is no need to prepend
|
||||
// AD user login with domain. On other platforms at the moment only
|
||||
// Basic authentication is supported
|
||||
var authType = AuthType.Basic;
|
||||
|
||||
//var connection = new LdapConnection(ldapServer)
|
||||
var connection = new LdapConnection(
|
||||
new LdapDirectoryIdentifier(ldapServer, ldapPort)
|
||||
)
|
||||
var dci = DataContext.Instance;
|
||||
var nonAssociatedUsers = dci.Users.Where(u => string.IsNullOrEmpty(u.LdapUserName) && !u.AssociationInProgress);
|
||||
var needsSaving = false;
|
||||
foreach (var user in nonAssociatedUsers)
|
||||
{
|
||||
AuthType = authType,
|
||||
Credential = new(username, password)
|
||||
};
|
||||
// the default one is v2 (at least in that version), and it is unknown if v3
|
||||
// is actually needed, but at least Synology LDAP works only with v3,
|
||||
// and since our Exchange doesn't complain, let it be v3
|
||||
connection.SessionOptions.ProtocolVersion = 3;
|
||||
user.AssociationInProgress = true;
|
||||
|
||||
startUserAssociationProcess(user);
|
||||
user.IsIntroduced = true;
|
||||
needsSaving = true;
|
||||
}
|
||||
|
||||
// this is for connecting via LDAPS (636 port). It should be working,
|
||||
// according to https://github.com/dotnet/runtime/issues/43890,
|
||||
// but it doesn't (at least with Synology DSM LDAP), although perhaps
|
||||
// for a different reason
|
||||
//connection.SessionOptions.SecureSocketLayer = true;
|
||||
if (needsSaving)
|
||||
{
|
||||
await dci.SaveChangesAsync();
|
||||
}
|
||||
await dci.DisposeAsync();
|
||||
};
|
||||
ldapAssociationTimer.Start();
|
||||
|
||||
connection.Bind();
|
||||
|
||||
var request = new SearchRequest(targetOU, query, scope, attributeList);
|
||||
|
||||
return (SearchResponse)connection.SendRequest(request);
|
||||
}
|
||||
|
||||
var searchResults = SearchInAD(
|
||||
AppConfiguration.Instance.LDAPConfig.LDAPserver,
|
||||
AppConfiguration.Instance.LDAPConfig.Port,
|
||||
AppConfiguration.Instance.LDAPConfig.Username,
|
||||
AppConfiguration.Instance.LDAPConfig.Password,
|
||||
var searchResults = LdapIntegration.Instance.SearchInAD(
|
||||
AppConfiguration.Instance.LDAPConfig.LDAPQueryBase,
|
||||
new StringBuilder("(&")
|
||||
.Append("(objectCategory=person)")
|
||||
.Append("(objectClass=user)")
|
||||
.Append($"(memberOf={_configurationAD.Crew})")
|
||||
.Append("(!(userAccountControl:1.2.840.113556.1.4.803:=2))")
|
||||
.Append(")")
|
||||
.ToString(),
|
||||
SearchScope.Subtree,
|
||||
attributesToQuery
|
||||
$"(memberOf={AppConfiguration.Instance.LDAPConfig.CrewGroup})",
|
||||
SearchScope.Subtree
|
||||
);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddOpenApi();
|
||||
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/Auth/Login";
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton<LdapAuthenticationService>();
|
||||
builder.Services.AddSingleton<PhoneClaimCodeProviderService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -188,5 +175,15 @@ app.UseAuthorization();
|
||||
app.MapStaticAssets();
|
||||
app.MapRazorPages()
|
||||
.WithStaticAssets();
|
||||
app.MapControllerRoute(
|
||||
name: "login",
|
||||
pattern: "{controller=Auth}/{action=Login}"
|
||||
);
|
||||
app.MapControllerRoute(
|
||||
name: "logout",
|
||||
pattern: "{controller=Auth}/{action=Logout}"
|
||||
);
|
||||
app.MapGet("/debug/routes", (IEnumerable<EndpointDataSource> endpointSources) =>
|
||||
string.Join("\n", endpointSources.SelectMany(source => source.Endpoints)));
|
||||
|
||||
app.Run();
|
||||
Reference in New Issue
Block a user