Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
b3cc35e
Refactoring
antomys May 2, 2021
b29f3ba
Fixed namespaces
antomys May 2, 2021
3949225
refactoring. Added client
antomys May 2, 2021
1772e0a
Some refactoring
antomys May 2, 2021
65dc971
Splitting project into layers
antomys May 14, 2021
f56a7e7
Some refactoring
antomys May 14, 2021
d5c556e
Some more refactoring
antomys May 14, 2021
83f4b38
Cleared controllers
antomys May 14, 2021
1c98c2f
Added memorycache
antomys May 14, 2021
18f7cea
Initial addition of JWT
antomys Jun 10, 2021
04c206b
Added and COMPLETELY changed Authorization. Added new cool feature OneOf
Jul 11, 2021
7d8dae6
Updated versions
Jul 11, 2021
e0b744d
Deleted exceptions.
Jul 13, 2021
a1f2bae
IMplemented Rooms logic (almost)
Jul 13, 2021
ee08dff
Implemented CleanerHostedService.cs
Jul 14, 2021
bd0821e
Added new Migrations
Jul 14, 2021
3934c90
Somewhat refactored Client
Jul 15, 2021
13a36e2
Added Statistics
Jul 15, 2021
7072f33
Update
Jul 16, 2021
bd027d6
Some more tweaks
Jul 17, 2021
46901ae
bugfix join room
Jul 20, 2021
b14f191
Added statistics
Jul 20, 2021
ae1e238
Merge pull request #18 from antomys/feature/signalr
antomys Jul 20, 2021
ab560fb
update of StatisticsService.cs
Jul 21, 2021
70e1d77
tweaks
Jul 21, 2021
d3c886f
More fixing
Jul 21, 2021
5b81d95
Fixed bot
Jul 21, 2021
083524e
Some tweaks
antomys Jan 9, 2022
452be65
Sealing + scoped
antomys Apr 26, 2022
c32806b
More sealing
antomys Apr 26, 2022
1b63782
More fixes. Sealing, cleaning. Todo: refactor logic and tests
May 1, 2022
c60177a
Fixed AuthService.cs
May 2, 2022
10e699a
More bugfixes and refactoring
May 6, 2022
bc5393a
Update dotnet.yml
antomys May 6, 2022
4ad7aa4
Refactored entities
May 7, 2022
45655b5
More fixes, simplified and fixed Entities. Fixed and improves Server.…
May 7, 2022
46085b7
Adding Migration
May 7, 2022
15dd8c7
Fixed entities. Added migrations. Wip with services.
May 7, 2022
0d8af08
Added documentation for completed Server.Authentication.csproj module.
May 7, 2022
85102fe
Some more tweaks
May 8, 2022
79c0a4e
Fixed roomController
May 8, 2022
298e574
Refactoring of controllers
May 8, 2022
2f076d1
Added new Properties
May 14, 2022
26433e4
Fixed Deps
antomys Aug 6, 2022
cf0d211
Added trello board
antomys Sep 4, 2022
6794b69
Added migration. Removed setters
antomys Oct 13, 2022
df6f120
Fixed and updates
antomys Oct 15, 2022
2337885
Refactored everything
antomys Oct 15, 2022
e95f886
removed global.json
antomys Oct 15, 2022
49348c3
Added healthchecks
antomys Oct 15, 2022
1062f21
Added mock for Main menu logic
antomys Oct 16, 2022
4efaf48
Added constant templates
antomys Oct 16, 2022
f3a2b52
Swagger fixes
antomys Oct 23, 2022
38df069
More fixes
antomys Oct 23, 2022
5dd9d4f
More fixes and improvements
antomys Oct 23, 2022
e5f20ea
Added IOptions and removed ILongPollingService.cs
antomys Oct 23, 2022
5222d3a
Added swagger title
antomys Oct 23, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: 5.0.201
dotnet-version: '6.0.x'
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand Down
17 changes: 0 additions & 17 deletions Client/Client - Backup.csproj

This file was deleted.

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

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

<ItemGroup>
<ProjectReference Include="..\..\Common\RockPaperScissors.Common\RockPaperScissors.Common.csproj" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions Client/Client.Account/Enums/MenuTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Client.Account.Enums;

internal enum MenuTypes
{
Unknown = 0,
SignUp = 1,
Login = 2,
Back = 3,
}
39 changes: 39 additions & 0 deletions Client/Client.Account/Extensions/EnumExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Client.Account.Enums;

namespace Client.Account.Extensions;

internal static class EnumExtensions
{
internal static string GetDisplayName(this MenuTypes menuTypes)
{
return menuTypes switch
{
MenuTypes.Back => "Back",
MenuTypes.Login => "Login",
MenuTypes.SignUp => "Sign Up",
_ => "Unknown",
};
}

internal static MenuTypes TryGetMenuType(this string? stringInput)
{
return stringInput switch
{
"3" => MenuTypes.Back,
"2" => MenuTypes.Login,
"1" => MenuTypes.SignUp,
_ => MenuTypes.Unknown,
};
}

internal static int GetValue(this MenuTypes menuTypes)
{
return menuTypes switch
{
MenuTypes.Back => 3,
MenuTypes.Login => 2,
MenuTypes.SignUp => 1,
_ => 0,
};
}
}
19 changes: 19 additions & 0 deletions Client/Client.Account/Extensions/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Client.Account.Menus;
using Client.Account.Services;
using Client.Account.Services.Interfaces;
using RockPaperScissors.Common.Client;

namespace Client.Account.Extensions;

public static class ServiceCollectionExtensions
{
public static IAccountService CreateAccountService(this IClient client)
{
return new AccountService(client);
}

public static IAccountMenu CreateAccountMenu(this IAccountService accountService)
{
return new AccountMenu(accountService);
}
}
160 changes: 160 additions & 0 deletions Client/Client.Account/Menus/AccountMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using Client.Account.Enums;
using Client.Account.Extensions;
using Client.Account.Services;
using Client.Account.Services.Interfaces;
using RockPaperScissors.Common.Enums;
using RockPaperScissors.Common.Extensions;

namespace Client.Account.Menus;

internal sealed class AccountMenu : IAccountMenu
{
private readonly IAccountService _accountService;

public AccountMenu(IAccountService accountService)
{
_accountService = accountService ?? throw new ArgumentNullException(nameof(accountService));
}

public async Task StartAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
"Account Menu:".Print(ConsoleColor.DarkYellow);
$"{MenuTypes.SignUp.GetValue()}.\t{MenuTypes.SignUp.GetDisplayName()}".Print(ConsoleColor.DarkYellow);
$"{MenuTypes.Login.GetValue()}.\t{MenuTypes.Login.GetDisplayName()}".Print(ConsoleColor.DarkYellow);
$"{MenuTypes.Back.GetValue()}.\t{MenuTypes.Back.GetDisplayName()}".Print(ConsoleColor.DarkYellow);

"\nPlease select an item from the list".Print(ConsoleColor.Green);

Console.Write("Select -> ");

var menuType = Console.ReadLine().TryGetMenuType();

if (menuType is MenuTypes.Unknown)
{
"Invalid input. Try again.".Print(ConsoleColor.Red);

continue;
}

switch (menuType)
{
case MenuTypes.SignUp:
var isRegistered = await RegisterAsync(cancellationToken);

if (!isRegistered)
{
"\nPress any key to back to the start up menu list!".Print(ConsoleColor.Cyan);
Console.ReadKey();
Console.Clear();

continue;
}

"Trying logging in...".Print(ConsoleColor.White);
Console.Clear();

return;

case MenuTypes.Login:
var isSuccess = await LoginAsync(cancellationToken);

if (isSuccess)
{
"\nPress any key to back to the start up menu list!".Print(ConsoleColor.Cyan);
Console.ReadKey();
Console.Clear();

return;
}

continue;

case MenuTypes.Back:
Console.Clear();

return;

default:
"Invalid input. Try again.".Print(ConsoleColor.Red);
continue;
}
}
}

public async Task<bool> LogoutAsync(CancellationToken cancellationToken)
{
if (!_accountService.IsAuthorized())
{
return true;
}

var user = _accountService.GetUser();

var response = await _accountService.LogoutAsync(user.SessionId, cancellationToken);

return response.Match(
_ =>
{
"Successfully signed out".Print(ConsoleColor.DarkGreen);

return true;
},
exception =>
{
exception.Message.Print(ConsoleColor.Red);

return false;
});
}

private async Task<bool> RegisterAsync(CancellationToken cancellationToken)
{
("We are glad to welcome you in the registration form!\n" +
"Please enter the required details\n" +
"to register an account on the platform")
.Print(ConsoleColor.Magenta);

var login = "Login: ".BuildString(StringDestination.Login);
var password = "Password: ".BuildString(StringDestination.Password);

var response = await _accountService.SignUpAsync(login, password, cancellationToken);

return response.Match(
_ =>
{
"Successfully registered!".Print(ConsoleColor.Green);

return true;
},
exception =>
{
exception.Message.Print(ConsoleColor.Red);

return false;
});
}

private async Task<bool> LoginAsync(CancellationToken cancellationToken)
{
var login = "Login: ".BuildString(StringDestination.Login);
var password = "Password: ".BuildString(StringDestination.Password, isNeedConfirmation: true);

var response = await _accountService.LoginAsync(login, password, cancellationToken);

return response.Match(
_ =>
{
"Successfully signed in".Print(ConsoleColor.DarkGreen);

return true;
},
exception =>
{
exception.Message.Print(ConsoleColor.Red);

return false;
});
}
}
8 changes: 8 additions & 0 deletions Client/Client.Account/Menus/IAccountMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Client.Account.Menus;

public interface IAccountMenu
{
Task StartAsync(CancellationToken cancellationToken);

Task<bool> LogoutAsync(CancellationToken cancellationToken);
}
105 changes: 105 additions & 0 deletions Client/Client.Account/Services/AccountService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Client.Account.Services.Interfaces;
using OneOf;
using RockPaperScissors.Common;
using RockPaperScissors.Common.Client;
using RockPaperScissors.Common.Extensions;
using RockPaperScissors.Common.Requests;
using RockPaperScissors.Common.Responses;

namespace Client.Account.Services;

internal sealed class AccountService : IAccountService
{
private readonly IClient _client;
private IUser _user = null!;

public AccountService(IClient client)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
}

public Task<OneOf<string, CustomException>> SignUpAsync(
string login, string password, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(login))
{
return Task.FromResult(OneOf<string, CustomException>.FromT1(new CustomException("Login must not be 'null' or '\"\"'")));
}

if (string.IsNullOrEmpty(password))
{
return Task.FromResult(OneOf<string, CustomException>.FromT1(new CustomException("Password must not be 'null' or '\"\"'")));
}

var request = new RegisterRequest
{
Login = login,
Password = password
};

var response =
_client.PostAsync<string, RegisterRequest>("api/Account/register", request, cancellationToken);

return response;
}

public async Task<OneOf<LoginResponse, CustomException>> LoginAsync(
string login, string password, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(login))
{
return new CustomException("Login must not be 'null' or '\"\"'");
}

if (string.IsNullOrEmpty(password))
{
return new CustomException("Password must not be 'null' or '\"\"'");
}

var request = new LoginRequest
{
Login = login,
Password = password
};

var response =
await _client.PostAsync<LoginResponse, LoginRequest>("api/Account/login", request, cancellationToken);

if (!response.IsT0)
{
return response;
}

var loginResponse = response.AsT0;
_user = new User(loginResponse.Token, loginResponse.Login);

return response;
}

public Task<OneOf<int, CustomException>> LogoutAsync(
string? token, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(token))
{
return Task.FromResult(OneOf<int, CustomException>.FromT1(new CustomException("Token must not be 'null' or '\"\"'")));
}

var queryUrl = new QueryBuilder(1)
{
{ "sessionId", token }
};
var url = $"api/Account/logout{queryUrl}";

var response =
_client.GetAsync<int>(url, ("Authorization", token), cancellationToken);

return response;
}

public IUser GetUser() => _user;

public bool IsAuthorized()
{
return _user is not null && _user.IsAuthorized;
}
}
Loading