diff --git a/QRBee.Core/Client/APIClient.nswag b/QRBee.Core/Client/APIClient.nswag
index 831c79a..4dee2bb 100644
--- a/QRBee.Core/Client/APIClient.nswag
+++ b/QRBee.Core/Client/APIClient.nswag
@@ -3,7 +3,7 @@
"defaultVariables": null,
"documentGenerator": {
"fromDocument": {
- "json": "{\r\n \"openapi\": \"3.0.1\",\r\n \"info\": {\r\n \"title\": \"QRBee.Api\",\r\n \"version\": \"1.0\"\r\n },\r\n \"paths\": {\r\n \"/api/QRBee/Register\": {\r\n \"post\": {\r\n \"tags\": [\r\n \"QRBee\"\r\n ],\r\n \"requestBody\": {\r\n \"content\": {\r\n \"application/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n },\r\n \"text/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n },\r\n \"application/*+json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n }\r\n }\r\n },\r\n \"responses\": {\r\n \"200\": {\r\n \"description\": \"Success\",\r\n \"content\": {\r\n \"text/plain\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationResponse\"\r\n }\r\n },\r\n \"application/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationResponse\"\r\n }\r\n },\r\n \"text/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationResponse\"\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n },\r\n \"components\": {\r\n \"schemas\": {\r\n \"RegistrationRequest\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"name\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"email\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"dateOfBirth\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"certificateRequest\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"registerAsMerchant\": {\r\n \"type\": \"boolean\"\r\n }\r\n },\r\n \"additionalProperties\": false\r\n },\r\n \"RegistrationResponse\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"clientId\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"certificate\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n }\r\n },\r\n \"additionalProperties\": false\r\n }\r\n }\r\n }\r\n}",
+ "json": "{\r\n \"openapi\": \"3.0.1\",\r\n \"info\": {\r\n \"title\": \"QRBee.Api\",\r\n \"version\": \"1.0\"\r\n },\r\n \"paths\": {\r\n \"/api/QRBee/Register\": {\r\n \"post\": {\r\n \"tags\": [\r\n \"QRBee\"\r\n ],\r\n \"requestBody\": {\r\n \"content\": {\r\n \"application/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n },\r\n \"text/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n },\r\n \"application/*+json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n }\r\n }\r\n },\r\n \"responses\": {\r\n \"200\": {\r\n \"description\": \"Success\",\r\n \"content\": {\r\n \"text/plain\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationResponse\"\r\n }\r\n },\r\n \"application/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationResponse\"\r\n }\r\n },\r\n \"text/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationResponse\"\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n },\r\n \"/api/QRBee/Update/{clientId}\": {\r\n \"patch\": {\r\n \"tags\": [\r\n \"QRBee\"\r\n ],\r\n \"parameters\": [\r\n {\r\n \"name\": \"clientId\",\r\n \"in\": \"path\",\r\n \"required\": true,\r\n \"schema\": {\r\n \"type\": \"string\"\r\n }\r\n }\r\n ],\r\n \"requestBody\": {\r\n \"content\": {\r\n \"application/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n },\r\n \"text/json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n },\r\n \"application/*+json\": {\r\n \"schema\": {\r\n \"$ref\": \"#/components/schemas/RegistrationRequest\"\r\n }\r\n }\r\n }\r\n },\r\n \"responses\": {\r\n \"200\": {\r\n \"description\": \"Success\"\r\n }\r\n }\r\n }\r\n }\r\n },\r\n \"components\": {\r\n \"schemas\": {\r\n \"RegistrationRequest\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"name\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"email\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"dateOfBirth\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"certificateRequest\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"registerAsMerchant\": {\r\n \"type\": \"boolean\"\r\n }\r\n },\r\n \"additionalProperties\": false\r\n },\r\n \"RegistrationResponse\": {\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"clientId\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n },\r\n \"certificate\": {\r\n \"type\": \"string\",\r\n \"nullable\": true\r\n }\r\n },\r\n \"additionalProperties\": false\r\n }\r\n }\r\n }\r\n}",
"url": "http://redocly.github.io/redoc/openapi.yaml",
"output": null,
"newLineBehavior": "Auto"
diff --git a/QRBee.Core/Client/Client.cs b/QRBee.Core/Client/Client.cs
index 4df7dc1..9a1b912 100644
--- a/QRBee.Core/Client/Client.cs
+++ b/QRBee.Core/Client/Client.cs
@@ -130,6 +130,81 @@ namespace QRBee.Core.Client
}
}
+ /// Success
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task UpdateAsync(string clientId, RegistrationRequest body)
+ {
+ return UpdateAsync(clientId, body, System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ /// Success
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task UpdateAsync(string clientId, RegistrationRequest body, System.Threading.CancellationToken cancellationToken)
+ {
+ if (clientId == null)
+ throw new System.ArgumentNullException("clientId");
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/QRBee/Update/{clientId}");
+ urlBuilder_.Replace("{clientId}", System.Uri.EscapeDataString(ConvertToString(clientId, System.Globalization.CultureInfo.InvariantCulture)));
+
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value));
+ content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("PATCH");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200)
+ {
+ return;
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
protected struct ObjectResponseResult
{
public ObjectResponseResult(T responseObject, string responseText)
diff --git a/QRBee/QRBee/Services/ILocalSettings.cs b/QRBee/QRBee/Services/ILocalSettings.cs
index 37ead0c..b1ebbcf 100644
--- a/QRBee/QRBee/Services/ILocalSettings.cs
+++ b/QRBee/QRBee/Services/ILocalSettings.cs
@@ -8,8 +8,9 @@ namespace QRBee.Services
public class Settings
{
//TODO add ClientId
+ public string ClientId { get; set; }
public string PIN { get; set; }
- public bool IsRegistered { get; set; }
+ public bool IsRegistered => !string.IsNullOrWhiteSpace(ClientId);
public string Name { get; set; }
public string Email { get; set; }
diff --git a/QRBee/QRBee/ViewModels/RegisterViewModel.cs b/QRBee/QRBee/ViewModels/RegisterViewModel.cs
index 9306630..f48ac53 100644
--- a/QRBee/QRBee/ViewModels/RegisterViewModel.cs
+++ b/QRBee/QRBee/ViewModels/RegisterViewModel.cs
@@ -102,34 +102,50 @@ namespace QRBee.ViewModels
try
{
//TODO Check if ClientId already in LocalSettings. If Yes update data in database
+ var settings = localSettings.LoadSettings();
//save local settings
- var settings = new Settings
- {
- CardHolderName = CardHolderName,
- CardNumber = CardNumber,
- CVC = CVC,
- DateOfBirth = DateOfBirth,
- Email = Email,
- ExpirationDate = ExpirationDate,
- IsRegistered = true,
- IssueNo = IssueNo,
- ValidFrom = ValidFrom,
- Name = Name,
- PIN = Pin
- };
+ settings.CardHolderName = CardHolderName;
+ settings.CardNumber = CardNumber;
+ settings.CVC = CVC;
+ settings.DateOfBirth = DateOfBirth;
+ settings.Email = Email;
+ settings.ExpirationDate = ExpirationDate;
+ settings.IssueNo = IssueNo;
+ settings.ValidFrom = ValidFrom;
+ settings.Name = Name;
+ settings.PIN = Pin;
+
await localSettings.SaveSettings(settings);
- await service.RegisterAsync(new RegistrationRequest
+ var request = new RegistrationRequest
{
- DateOfBirth = DateOfBirth.ToString("yyyy-MM-dd"),
- Email = Email,
- Name = Name,
+ DateOfBirth = DateOfBirth.ToString("yyyy-MM-dd"),
+ Email = Email,
+ Name = Name,
RegisterAsMerchant = false
- });
+ };
+
+ if (!settings.IsRegistered)
+ {
+ var response = await service.RegisterAsync(request);
+
+ // Save ClientId to LocalSettings
+ settings = localSettings.LoadSettings();
+ settings.ClientId = response.ClientId;
+ await localSettings.SaveSettings(settings);
+
+ var page = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
+ await page.DisplayAlert("Success", "You have been registered successfully", "Ok");
+ }
+ else
+ {
+ await service.UpdateAsync(settings.ClientId, request);
+ var page = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
+ await page.DisplayAlert("Success", "Your data has been updated successfully", "Ok");
+ }
+
- var page = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
- await page.DisplayAlert("Success", "You have been registered successfully", "Ok");
await Shell.Current.GoToAsync($"//{nameof(MainPage)}");
}
diff --git a/QRBeeApi/Controllers/QRBeeController.cs b/QRBeeApi/Controllers/QRBeeController.cs
index 0ca1031..b93fd37 100644
--- a/QRBeeApi/Controllers/QRBeeController.cs
+++ b/QRBeeApi/Controllers/QRBeeController.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
+using MongoDB.Driver;
using QRBee.Api.Services;
using QRBee.Core;
using QRBee.Core.Data;
@@ -27,5 +28,11 @@ namespace QRBee.Api.Controllers
return _service.Register(value);
}
+ [HttpPatch("Update/{clientId}")]
+ public Task Update([FromRoute] string clientId, [FromBody] RegistrationRequest value)
+ {
+ _logger.LogInformation($"Trying to update user {value.Name}");
+ return _service.Update(clientId,value);
+ }
}
}
diff --git a/QRBeeApi/Services/Database/IStorage.cs b/QRBeeApi/Services/Database/IStorage.cs
index a37ae86..b362113 100644
--- a/QRBeeApi/Services/Database/IStorage.cs
+++ b/QRBeeApi/Services/Database/IStorage.cs
@@ -19,5 +19,7 @@
/// User information
Task GetUserInfo(string email);
+ Task UpdateUser(UserInfo info);
+
}
}
diff --git a/QRBeeApi/Services/Database/Storage.cs b/QRBeeApi/Services/Database/Storage.cs
index 6cb6b03..df59218 100644
--- a/QRBeeApi/Services/Database/Storage.cs
+++ b/QRBeeApi/Services/Database/Storage.cs
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Options;
using MongoDB.Driver;
+using QRBee.Api.Controllers;
namespace QRBee.Api.Services.Database
{
@@ -7,12 +8,14 @@ namespace QRBee.Api.Services.Database
{
private readonly IMongoDatabase _database;
+ private readonly ILogger _logger;
- public Storage(IMongoClient client, IOptions settings)
+ public Storage(IMongoClient client, IOptions settings, ILogger logger)
{
var name = settings.Value.DatabaseName;
_database = client.GetDatabase(name);
+ _logger = logger;
}
public async Task PutUserInfo(UserInfo info)
@@ -27,13 +30,20 @@ namespace QRBee.Api.Services.Database
if (user == null)
{
await collection.InsertOneAsync(info);
+ _logger.LogInformation($"Inserted new user with Email: {info.Email} and ID: {info.ClientId}");
return info.ClientId ?? throw new ApplicationException($"ClientId is null while adding user {info.Email}");
}
+
+ // Update command will not be used due to not knowing if the user is legitimate
+ _logger.LogInformation($"Found user with Email: {info.Email} and ID: {info.ClientId}");
return user.ClientId ?? throw new ApplicationException($"ClientId is null while adding user {info.Email}");
-
-
}
+ ///
+ /// Check if user already exists in database
+ ///
+ /// Parameter by which to find UserInfo
+ /// null if user doesn't exist or UserInfo
internal async Task TryGetUserInfo(string email)
{
var collection = _database.GetCollection("Users");
@@ -52,5 +62,11 @@ namespace QRBee.Api.Services.Database
return user ?? throw new ApplicationException($"User {email} not found.");
}
+ public async Task UpdateUser(UserInfo info)
+ {
+ var collection = _database.GetCollection("Users");
+ await collection.ReplaceOneAsync($"{{ _id: \"{info.Id}\" }}",info, new ReplaceOptions(){IsUpsert = false});
+ }
+
}
}
diff --git a/QRBeeApi/Services/IQRBeeAPI.cs b/QRBeeApi/Services/IQRBeeAPI.cs
index 5bc568c..cf64ebf 100644
--- a/QRBeeApi/Services/IQRBeeAPI.cs
+++ b/QRBeeApi/Services/IQRBeeAPI.cs
@@ -16,5 +16,12 @@ namespace QRBee.Api.Services
/// Registration response
Task Register(RegistrationRequest value);
+ ///
+ /// Handles Update request
+ ///
+ ///
+ /// Update request
+ Task Update(string clientId, RegistrationRequest value);
+
}
}
diff --git a/QRBeeApi/Services/QRBeeAPI.cs b/QRBeeApi/Services/QRBeeAPI.cs
index 492f896..f39bf31 100644
--- a/QRBeeApi/Services/QRBeeAPI.cs
+++ b/QRBeeApi/Services/QRBeeAPI.cs
@@ -26,13 +26,19 @@ namespace QRBee.Api.Services
Validate(request);
var info = Convert(request);
- //TODO Check that user doesn't exist(name,surname,dateOfBirth or Telephone number(get from Android))
var clientId = await _storage.PutUserInfo(info);
return new RegistrationResponse{ClientId = clientId};
}
- //TODO Write an UpdateUser command
+
+ public Task Update(string clientId, RegistrationRequest request)
+ {
+ Validate(request);
+ var info = Convert(request);
+ return _storage.UpdateUser(info);
+ }
+
private static void Validate(RegistrationRequest request)
{
if (request == null)
@@ -66,7 +72,7 @@ namespace QRBee.Api.Services
}
- private UserInfo Convert(RegistrationRequest request)
+ private static UserInfo Convert(RegistrationRequest request)
{
return new UserInfo(request.Name, request.Email, request.DateOfBirth);
}