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;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[HttpPost("Register")]
|
||||
public Task<RegistrationResponse> Register([FromBody] RegistrationRequest value)
|
||||
{
|
||||
return _service.Register(value);
|
||||
|
||||
@ -5,6 +5,7 @@ namespace QRBee.Api
|
||||
public class DatabaseSettings
|
||||
{
|
||||
public string? ConnectionString { get; set;}
|
||||
public string? DatabaseName { get; set; }
|
||||
|
||||
public MongoClientSettings ToMongoDbSettings()
|
||||
{
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using QRBee.Api;
|
||||
using QRBee.Api.Services;
|
||||
@ -12,10 +13,12 @@ builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.AddSingleton<IQRBeeAPI,QRBeeAPI>();
|
||||
builder.Services.AddSingleton<IStorage, Storage>();
|
||||
builder.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("QRBeeDatabase"));
|
||||
builder.Services.AddSingleton<IMongoClient>( cfg => new MongoClient(cfg.GetRequiredService<DatabaseSettings>().ToMongoDbSettings()));
|
||||
builder.Services
|
||||
.AddSingleton<IQRBeeAPI,QRBeeAPI>()
|
||||
.AddSingleton<IStorage, Storage>()
|
||||
.Configure<DatabaseSettings>(builder.Configuration.GetSection("QRBeeDatabase"))
|
||||
.AddSingleton<IMongoClient>( cfg => new MongoClient(cfg.GetRequiredService<IOptions<DatabaseSettings>>().Value.ToMongoDbSettings()))
|
||||
;
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace QRBee.Api.Services
|
||||
namespace QRBee.Api.Services.Database
|
||||
{
|
||||
public interface IStorage
|
||||
{
|
||||
|
||||
void PutUserInfo(UserInfo info);
|
||||
UserInfo GetUserInfo(string email);
|
||||
Task<string> PutUserInfo(UserInfo info);
|
||||
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 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
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
public UserInfo()
|
||||
#pragma warning restore CS8618
|
||||
{
|
||||
|
||||
}
|
||||
@ -14,27 +19,14 @@ public record UserInfo
|
||||
DateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public string? Name
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// Never use directly. Use <see cref="ClientId"/> instead.
|
||||
/// </summary>
|
||||
[BsonId] public ObjectId Id { get; set; }
|
||||
|
||||
public string? Email
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string? DateOfBirth
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool RegisterAsMerchant
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
[BsonIgnore] public string? ClientId => Id == ObjectId.Empty ? null : Id.ToString();
|
||||
public string Name { get; set; }
|
||||
public string Email { 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.Data;
|
||||
|
||||
@ -7,32 +9,27 @@ namespace QRBee.Api.Services
|
||||
public class QRBeeAPI: IQRBeeAPI
|
||||
{
|
||||
private readonly IStorage _storage;
|
||||
private const int MaxNameLength = 512;
|
||||
private const int MaxEmailLength = 512;
|
||||
|
||||
public QRBeeAPI(IStorage storage)
|
||||
{
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public Task<RegistrationResponse> Register(RegistrationRequest request)
|
||||
public async Task<RegistrationResponse> Register(RegistrationRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
Validate(request);
|
||||
|
||||
var info = Convert(request);
|
||||
|
||||
if (UserExists(info))
|
||||
{
|
||||
// throw error
|
||||
}
|
||||
else
|
||||
{
|
||||
_storage.PutUserInfo(info);
|
||||
var clientId = await _storage.PutUserInfo(info);
|
||||
|
||||
return new RegistrationResponse{ClientId = clientId};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Validate(RegistrationRequest request)
|
||||
private static void Validate(RegistrationRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
@ -43,19 +40,25 @@ namespace QRBee.Api.Services
|
||||
var email = request.Email;
|
||||
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);
|
||||
}
|
||||
|
||||
private bool UserExists(UserInfo info)
|
||||
{
|
||||
var user = _storage.GetUserInfo(info.Email);
|
||||
|
||||
return user == info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,7 @@
|
||||
|
||||
"QRBeeDatabase": {
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "QRBee",
|
||||
"User": "",
|
||||
"Password": ""
|
||||
"DatabaseName": "QRBee"
|
||||
},
|
||||
|
||||
"Logging": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user