mirror of
https://github.com/NecroticBamboo/QRBee.git
synced 2025-12-21 12:11:53 +00:00
MongoDB connected. User registration implemented.
This commit is contained in:
parent
2525e37f83
commit
96411f70f7
@ -18,7 +18,7 @@ namespace QRBee.Api.Controllers
|
|||||||
_service = service;
|
_service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost("Register")]
|
||||||
public Task<RegistrationResponse> Register([FromBody] RegistrationRequest value)
|
public Task<RegistrationResponse> Register([FromBody] RegistrationRequest value)
|
||||||
{
|
{
|
||||||
return _service.Register(value);
|
return _service.Register(value);
|
||||||
|
|||||||
@ -5,6 +5,7 @@ namespace QRBee.Api
|
|||||||
public class DatabaseSettings
|
public class DatabaseSettings
|
||||||
{
|
{
|
||||||
public string? ConnectionString { get; set;}
|
public string? ConnectionString { get; set;}
|
||||||
|
public string? DatabaseName { get; set; }
|
||||||
|
|
||||||
public MongoClientSettings ToMongoDbSettings()
|
public MongoClientSettings ToMongoDbSettings()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using QRBee.Api;
|
using QRBee.Api;
|
||||||
using QRBee.Api.Services;
|
using QRBee.Api.Services;
|
||||||
@ -12,10 +13,12 @@ builder.Services.AddControllers();
|
|||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
builder.Services.AddSingleton<IQRBeeAPI,QRBeeAPI>();
|
builder.Services
|
||||||
builder.Services.AddSingleton<IStorage, Storage>();
|
.AddSingleton<IQRBeeAPI,QRBeeAPI>()
|
||||||
builder.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("QRBeeDatabase"));
|
.AddSingleton<IStorage, Storage>()
|
||||||
builder.Services.AddSingleton<IMongoClient>( cfg => new MongoClient(cfg.GetRequiredService<DatabaseSettings>().ToMongoDbSettings()));
|
.Configure<DatabaseSettings>(builder.Configuration.GetSection("QRBeeDatabase"))
|
||||||
|
.AddSingleton<IMongoClient>( cfg => new MongoClient(cfg.GetRequiredService<IOptions<DatabaseSettings>>().Value.ToMongoDbSettings()))
|
||||||
|
;
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
using Microsoft.AspNetCore.Identity;
|
namespace QRBee.Api.Services.Database
|
||||||
|
|
||||||
namespace QRBee.Api.Services
|
|
||||||
{
|
{
|
||||||
public interface IStorage
|
public interface IStorage
|
||||||
{
|
{
|
||||||
|
|
||||||
void PutUserInfo(UserInfo info);
|
Task<string> PutUserInfo(UserInfo info);
|
||||||
UserInfo GetUserInfo(string email);
|
Task<UserInfo> GetUserInfo(string email);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,56 @@
|
|||||||
namespace QRBee.Api.Services.Database
|
using Microsoft.Extensions.Options;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
|
namespace QRBee.Api.Services.Database
|
||||||
{
|
{
|
||||||
public class Storage: IStorage
|
public class Storage: IStorage
|
||||||
{
|
{
|
||||||
public void PutUserInfo(UserInfo info)
|
|
||||||
|
private readonly IMongoDatabase _database;
|
||||||
|
|
||||||
|
public Storage(IMongoClient client, IOptions<DatabaseSettings> settings)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var name = settings.Value.DatabaseName;
|
||||||
|
|
||||||
|
_database = client.GetDatabase(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserInfo GetUserInfo(string email)
|
public async Task<string> PutUserInfo(UserInfo info)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
|
||||||
|
var collection = _database.GetCollection<UserInfo>("Users");
|
||||||
|
|
||||||
|
var user = await TryGetUserInfo(info.Email);
|
||||||
|
|
||||||
|
// Ignore re-register
|
||||||
|
// Potential vulnerability if user registers with other email
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
await collection.InsertOneAsync(info);
|
||||||
|
return info.ClientId ?? throw new ApplicationException($"ClientId is null while adding user {info.Email}");
|
||||||
|
}
|
||||||
|
return user.ClientId ?? throw new ApplicationException($"ClientId is null while adding user {info.Email}");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal async Task<UserInfo?> TryGetUserInfo(string email)
|
||||||
|
{
|
||||||
|
var collection = _database.GetCollection<UserInfo>("Users");
|
||||||
|
using var cursor = await collection.FindAsync($"{{ Email: \"{email}\" }}");
|
||||||
|
if (!await cursor.MoveNextAsync())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor.Current.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserInfo> GetUserInfo(string email)
|
||||||
|
{
|
||||||
|
var user = await TryGetUserInfo(email);
|
||||||
|
return user ?? throw new ApplicationException($"User {email} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
namespace QRBee.Api.Services;
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
|
||||||
|
namespace QRBee.Api.Services.Database;
|
||||||
|
|
||||||
public record UserInfo
|
public record UserInfo
|
||||||
{
|
{
|
||||||
|
#pragma warning disable CS8618
|
||||||
public UserInfo()
|
public UserInfo()
|
||||||
|
#pragma warning restore CS8618
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -14,27 +19,14 @@ public record UserInfo
|
|||||||
DateOfBirth = dateOfBirth;
|
DateOfBirth = dateOfBirth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? Name
|
/// <summary>
|
||||||
{
|
/// Never use directly. Use <see cref="ClientId"/> instead.
|
||||||
get;
|
/// </summary>
|
||||||
set;
|
[BsonId] public ObjectId Id { get; set; }
|
||||||
}
|
|
||||||
|
|
||||||
public string? Email
|
[BsonIgnore] public string? ClientId => Id == ObjectId.Empty ? null : Id.ToString();
|
||||||
{
|
public string Name { get; set; }
|
||||||
get;
|
public string Email { get; set; }
|
||||||
set;
|
public string DateOfBirth { get; set; }
|
||||||
}
|
public bool RegisterAsMerchant { get; set; }
|
||||||
|
|
||||||
public string? DateOfBirth
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RegisterAsMerchant
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Globalization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using QRBee.Api.Services.Database;
|
||||||
using QRBee.Core;
|
using QRBee.Core;
|
||||||
using QRBee.Core.Data;
|
using QRBee.Core.Data;
|
||||||
|
|
||||||
@ -7,32 +9,27 @@ namespace QRBee.Api.Services
|
|||||||
public class QRBeeAPI: IQRBeeAPI
|
public class QRBeeAPI: IQRBeeAPI
|
||||||
{
|
{
|
||||||
private readonly IStorage _storage;
|
private readonly IStorage _storage;
|
||||||
|
private const int MaxNameLength = 512;
|
||||||
|
private const int MaxEmailLength = 512;
|
||||||
|
|
||||||
public QRBeeAPI(IStorage storage)
|
public QRBeeAPI(IStorage storage)
|
||||||
{
|
{
|
||||||
_storage = storage;
|
_storage = storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<RegistrationResponse> Register(RegistrationRequest request)
|
public async Task<RegistrationResponse> Register(RegistrationRequest request)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
|
||||||
|
|
||||||
Validate(request);
|
Validate(request);
|
||||||
|
|
||||||
var info = Convert(request);
|
var info = Convert(request);
|
||||||
|
|
||||||
if (UserExists(info))
|
var clientId = await _storage.PutUserInfo(info);
|
||||||
{
|
|
||||||
// throw error
|
return new RegistrationResponse{ClientId = clientId};
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_storage.PutUserInfo(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private static void Validate(RegistrationRequest request)
|
||||||
|
|
||||||
private void Validate(RegistrationRequest request)
|
|
||||||
{
|
{
|
||||||
if (request == null)
|
if (request == null)
|
||||||
{
|
{
|
||||||
@ -43,19 +40,25 @@ namespace QRBee.Api.Services
|
|||||||
var email = request.Email;
|
var email = request.Email;
|
||||||
var dateOfBirth = request.DateOfBirth;
|
var dateOfBirth = request.DateOfBirth;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(name) || name.All(char.IsLetter)==false || name.Length>=30)
|
if (string.IsNullOrEmpty(name) || name.All(char.IsLetter)==false || name.Length>=MaxNameLength)
|
||||||
{
|
{
|
||||||
// throw exception
|
throw new ApplicationException($"Name \"{name}\" isn't valid");
|
||||||
}
|
}
|
||||||
|
|
||||||
var freq = Regex.Matches(email, '@'.ToString()).Count;
|
var freq = Regex.Matches(email, @"[^@]+@[^@]+").Count;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(email) || email.Contains('@')==false || freq>=2 || email.Length >= 30)
|
if (string.IsNullOrEmpty(email) || email.IndexOf('@')<0 || freq>=2 || email.Length >= MaxEmailLength)
|
||||||
{
|
{
|
||||||
// throw exception
|
throw new ApplicationException($"Email \"{email}\" isn't valid");
|
||||||
}
|
}
|
||||||
|
|
||||||
// DateOfBirth check
|
if (!DateTime.TryParseExact(dateOfBirth, "yyyy-MM-dd", null, DateTimeStyles.AssumeUniversal, out var check)
|
||||||
|
|| check > DateTime.UtcNow - TimeSpan.FromDays(365 * 8)
|
||||||
|
|| check < DateTime.UtcNow - TimeSpan.FromDays(365 * 100)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
throw new ApplicationException($"DateOfBirth \"{dateOfBirth}\" isn't valid");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +67,5 @@ namespace QRBee.Api.Services
|
|||||||
return new UserInfo(request.Name, request.Email, request.DateOfBirth);
|
return new UserInfo(request.Name, request.Email, request.DateOfBirth);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool UserExists(UserInfo info)
|
|
||||||
{
|
|
||||||
var user = _storage.GetUserInfo(info.Email);
|
|
||||||
|
|
||||||
return user == info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
"QRBeeDatabase": {
|
"QRBeeDatabase": {
|
||||||
"ConnectionString": "mongodb://localhost:27017",
|
"ConnectionString": "mongodb://localhost:27017",
|
||||||
"DatabaseName": "QRBee",
|
"DatabaseName": "QRBee"
|
||||||
"User": "",
|
|
||||||
"Password": ""
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"Logging": {
|
"Logging": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user