Skip to content

Commit

Permalink
added olive.mfa
Browse files Browse the repository at this point in the history
  • Loading branch information
AitzazTheGeek committed Feb 24, 2025
1 parent df90acc commit 008464b
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 4 deletions.
18 changes: 18 additions & 0 deletions Olive.MFA/IMFAManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Olive.MFA
{
using Olive.Email;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public interface IMFAManager
{
Task SendOtpViaEmail(IEmailMessage emailMessage);
Task<bool> SendOtpViaSms(string otp, string phoneNumber);
string GetOtp();


}
}
19 changes: 19 additions & 0 deletions Olive.MFA/ITemporaryLogin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Olive.MFA
{
using Olive.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

[LogEvents(false)]
[CacheObjects(false)]
public interface ITemporaryLogin : IEntity
{
DateTime CreatedAt { get; set; }
int ExpiryMinutes { get; set; }
string MFACode { get; set; }

}
}
15 changes: 15 additions & 0 deletions Olive.MFA/ITemporaryLoginService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Olive.MFA
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public interface ITemporaryLoginService
{
Task DeleteTemporaryLogin(ITemporaryLogin login);
Task<bool> IsSessionExpired(ITemporaryLogin login);
Task<bool> IsOtpValid(ITemporaryLogin login, string code);
}
}
20 changes: 20 additions & 0 deletions Olive.MFA/MFAExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Olive.MFA
{
using Microsoft.Extensions.DependencyInjection;
using Olive.SMS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public static class MFAExtensions
{
public static IServiceCollection AddMFA(this IServiceCollection @this)
{
return @this
.AddSingleton<IMFAManager, MFAManager>()
.AddSingleton<ITemporaryLoginService, TemporaryLoginService>();
}
}
}
49 changes: 49 additions & 0 deletions Olive.MFA/MFAManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
namespace Olive.MFA
{
using Olive.Email;
using Olive.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;

public class MFAManager : IMFAManager
{
IDatabase Database => Context.Current.Database();
public Task SendOtpViaEmail(IEmailMessage emailMessage)
{
return Database.Save(emailMessage);
}

public Task<bool> SendOtpViaSms(string otp, string phoneNumber)
{
var accountId = Config.Get("TwilioAccountId");
var authKey = Config.Get("TwilioAuthKey");
var sender = Config.Get("TwilioSenderNumber");

if (accountId.IsEmpty() || authKey.IsEmpty() || sender.IsEmpty())
throw new Exception("TwilioAccountId | TwilioAuthKey | TwilioSenderNumber configuration not set");



TwilioClient.Init(accountId, authKey);
var message = MessageResource.Create(
to: new PhoneNumber(phoneNumber),
from: new PhoneNumber(sender),
body: $"Your OTP code is: {otp}");

return Task.FromResult(message != null);
}
public string GetOtp()
{
var random = new Random();
var otp = random.Next(100000, 999999).ToString();
return otp;

}
}
}
18 changes: 18 additions & 0 deletions Olive.MFA/Olive.MFA.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Twilio" Version="7.8.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Olive.Email\Olive.Email.csproj" />
<ProjectReference Include="..\Olive.SMS\Olive.SMS.csproj" />
</ItemGroup>

</Project>
29 changes: 29 additions & 0 deletions Olive.MFA/TemporaryLoginService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Olive.MFA
{
using Olive.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class TemporaryLoginService : ITemporaryLoginService
{
IDatabase Database => Context.Current.Database();
public Task DeleteTemporaryLogin(ITemporaryLogin login)
{
return Database.Delete(login);
}

public async Task<bool> IsOtpValid(ITemporaryLogin login, string code)
{
return login.MFACode.HasValue() && login.CreatedAt.AddMinutes((double)login.ExpiryMinutes) > LocalTime.Now &&
login.MFACode.Equals(code);
}

public async Task<bool> IsSessionExpired(ITemporaryLogin login)
{
return login.CreatedAt.AddMinutes(login.ExpiryMinutes) < LocalTime.Now;
}
}
}
15 changes: 11 additions & 4 deletions Olive.sln
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Olive.Entities.Data.EF.Repl
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OpenAI", "OpenAI", "{EA662106-3384-4A6F-83C4-83859789A6DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Olive.OpenAI", "Olive.OpenAI\Olive.OpenAI\Olive.OpenAI.csproj", "{F7D375B0-4C0E-43F3-AE01-C35A0B01ED2C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Olive.OpenAI", "Olive.OpenAI\Olive.OpenAI\Olive.OpenAI.csproj", "{F7D375B0-4C0E-43F3-AE01-C35A0B01ED2C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Olive.OpenAI.Voice", "Olive.OpenAI.Voice\Olive.OpenAI.Voice\Olive.OpenAI.Voice.csproj", "{F96D0F3C-2F36-4897-A60B-B9F37793751D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Olive.OpenAI.Voice", "Olive.OpenAI.Voice\Olive.OpenAI.Voice\Olive.OpenAI.Voice.csproj", "{F96D0F3C-2F36-4897-A60B-B9F37793751D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Olive.Azure.DocumentAnalyzer", "Olive.Azure.DocumentAnalyzer\Olive.Azure.DocumentAnalyzer.csproj", "{1621EA95-F031-4FA2-BAA1-8CEDFA84D987}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Olive.Azure.DocumentAnalyzer", "Olive.Azure.DocumentAnalyzer\Olive.Azure.DocumentAnalyzer.csproj", "{1621EA95-F031-4FA2-BAA1-8CEDFA84D987}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Olive.Azure.DocumentClassification", "Olive.Azure.DocumentClassification\Olive.Azure.DocumentClassification.csproj", "{4CE3F810-F35F-40A2-83C5-529419ACEAD4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Olive.Azure.DocumentClassification", "Olive.Azure.DocumentClassification\Olive.Azure.DocumentClassification.csproj", "{4CE3F810-F35F-40A2-83C5-529419ACEAD4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Olive.MFA", "Olive.MFA\Olive.MFA.csproj", "{4D98F2B4-3B67-4A4D-8F90-7D4009F06EE3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -589,6 +591,10 @@ Global
{4CE3F810-F35F-40A2-83C5-529419ACEAD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CE3F810-F35F-40A2-83C5-529419ACEAD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CE3F810-F35F-40A2-83C5-529419ACEAD4}.Release|Any CPU.Build.0 = Release|Any CPU
{4D98F2B4-3B67-4A4D-8F90-7D4009F06EE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D98F2B4-3B67-4A4D-8F90-7D4009F06EE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D98F2B4-3B67-4A4D-8F90-7D4009F06EE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D98F2B4-3B67-4A4D-8F90-7D4009F06EE3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -689,6 +695,7 @@ Global
{F96D0F3C-2F36-4897-A60B-B9F37793751D} = {EA662106-3384-4A6F-83C4-83859789A6DD}
{1621EA95-F031-4FA2-BAA1-8CEDFA84D987} = {B08CEA40-4865-41AF-94CA-AC59E2513A11}
{4CE3F810-F35F-40A2-83C5-529419ACEAD4} = {B08CEA40-4865-41AF-94CA-AC59E2513A11}
{4D98F2B4-3B67-4A4D-8F90-7D4009F06EE3} = {B08CEA40-4865-41AF-94CA-AC59E2513A11}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B8459027-6FAF-42E6-B8A8-4887D7730704}
Expand Down

0 comments on commit 008464b

Please sign in to comment.