192 lines
6.6 KiB
C#
192 lines
6.6 KiB
C#
|
|
using Scalar.AspNetCore;
|
|
using Microsoft.AspNetCore.OpenApi;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using System.DirectoryServices.Protocols;
|
|
|
|
SignalIntegration.Instance = new SignalIntegration(AppConfiguration.Instance.SignalAPIEndpointUri,
|
|
int.Parse(AppConfiguration.Instance.SignalAPIEndpointPort),
|
|
AppConfiguration.Instance.HostPhoneNumber);
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
Console.WriteLine("Setting up user check timer");
|
|
var userCheckTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false);
|
|
userCheckTimer.OnOccurence += async (s, ea) =>
|
|
{
|
|
var memberList = await SignalIntegration.Instance.GetMemberListAsync();
|
|
var dci = DataContext.Instance;
|
|
var needsSaving = false;
|
|
foreach (var memberId in memberList)
|
|
{
|
|
Console.WriteLine("found member: " + memberId);
|
|
var foundUser = dci.Users.Where(u => u.SignalMemberId == memberId).SingleOrDefault();
|
|
if (foundUser == null)
|
|
{
|
|
var newUserContact = await SignalIntegration.Instance.GetContactAsync(memberId);
|
|
Console.WriteLine("New user:");
|
|
Console.WriteLine($" Name: {newUserContact.Name}");
|
|
Console.WriteLine($" MemberId: {memberId}");
|
|
User newUser = new User()
|
|
{
|
|
Name = newUserContact.Name,
|
|
SignalMemberId = memberId,
|
|
NickName = string.Empty,
|
|
IsIntroduced = false
|
|
};
|
|
dci.Users.Add(newUser);
|
|
needsSaving = true;
|
|
}
|
|
}
|
|
|
|
if (needsSaving)
|
|
{
|
|
await dci.SaveChangesAsync();
|
|
}
|
|
await dci.DisposeAsync();
|
|
};
|
|
//userCheckTimer.Start();
|
|
|
|
Console.WriteLine("Setting up user intro timer");
|
|
var userIntroTimer = new CronTimer("*/1 * * * *", "Europe/Vienna", includingSeconds: false);
|
|
userIntroTimer.OnOccurence += async (s, ea) =>
|
|
{
|
|
var dci = DataContext.Instance;
|
|
var introUsers = dci.Users.Where(u => !u.IsIntroduced);
|
|
bool needsSaving = false;
|
|
foreach (var user in introUsers)
|
|
{
|
|
await SignalIntegration.Instance.IntroduceUserAsync(user);
|
|
user.IsIntroduced = true;
|
|
needsSaving = true;
|
|
}
|
|
|
|
if (needsSaving)
|
|
{
|
|
await dci.SaveChangesAsync();
|
|
}
|
|
await dci.DisposeAsync();
|
|
};
|
|
//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 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;
|
|
SignalIntegration.Instance.SendMessageToGroupAsync($"Today's chosen person to share a song is: **{userName}**");
|
|
SignalIntegration.Instance.SendMessageToUserAsync($"Congratulations, you have been chosen to share a song today!", luckyUser.SignalMemberId);
|
|
var suggestion = await dci.SuggestionHelpers.ElementAtAsync((new Random()).Next(await dci.SuggestionHelpers.CountAsync()));
|
|
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();
|
|
|
|
var connection = new LdapConnection(AppConfiguration.Instance.LDAPConfig.LDAPserver)
|
|
{
|
|
Credential = new(
|
|
AppConfiguration.Instance.LDAPConfig.Username,
|
|
AppConfiguration.Instance.LDAPConfig.Password
|
|
)
|
|
};
|
|
|
|
var attributesToQuery = new string[]
|
|
{
|
|
"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)
|
|
)
|
|
{
|
|
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;
|
|
|
|
// 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;
|
|
|
|
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,
|
|
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
|
|
);
|
|
|
|
// Add services to the container.
|
|
builder.Services.AddRazorPages();
|
|
builder.Services.AddOpenApi();
|
|
|
|
var app = builder.Build();
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if (!app.Environment.IsDevelopment())
|
|
{
|
|
app.UseExceptionHandler("/Error");
|
|
}
|
|
else
|
|
{
|
|
app.MapOpenApi();
|
|
app.MapScalarApiReference();
|
|
}
|
|
|
|
app.UseRouting();
|
|
|
|
app.UseAuthorization();
|
|
|
|
app.MapStaticAssets();
|
|
app.MapRazorPages()
|
|
.WithStaticAssets();
|
|
|
|
app.Run(); |