first commit
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
using MassTransit;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using OpenWarehouse.warehouse.api.Common.ItemTagManager;
|
||||
using OpenWarehouse.warehouse.api.Common.Kafka;
|
||||
using OpenWarehouse.warehouse.api.Common.Kafka.TagTree;
|
||||
using OpenWarehouse.warehouse.api.Common.Producer;
|
||||
using OpenWarehouse.warehouse.api.Common.TaskManager;
|
||||
using OpenWarehouse.warehouse.api.Model.Item;
|
||||
using ActionResult = Microsoft.AspNetCore.Mvc.ActionResult;
|
||||
using ItemCategoryTag = OpenWarehouse.warehouse.api.Data.ItemCategoryTag;
|
||||
|
||||
namespace OpenWarehouse.warehouse.api.Controller;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
public class Item(IItemManager itemManager, ILogger<Item> logger,
|
||||
ITopicProducer<TagTreeKafkaMessage> publishTagTreeEndpoint, ITaskManager taskManager,
|
||||
IItemTagManager itemTagManager, IProducerManager producerManager) : ControllerBase
|
||||
{
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<ItemModel>> GetItemById([FromRoute] string id)
|
||||
{
|
||||
logger.LogInformation("GetItemById called for item id {id}", id);
|
||||
var item = await itemManager.FindItemByIdAsync(id);
|
||||
logger.LogDebug("Item retrieved: {@Item}", item);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
logger.LogWarning("Item with ID:{id} not found", id);
|
||||
return NotFound();
|
||||
}
|
||||
var result = new ItemModel()
|
||||
{
|
||||
Id = item.Id.ToString(),
|
||||
Name = item.Name,
|
||||
Claims = item.ItemClaims?.ToDictionary(
|
||||
q => q.ClaimType ?? $"Unknown type, {Guid.NewGuid()} ",
|
||||
q => new ClaimValueModel()
|
||||
{
|
||||
Issuer = q.ClaimIssuer,
|
||||
Value = q.ClaimValue,
|
||||
}),
|
||||
ProducerId = item.ProducerId.ToString(),
|
||||
ProducerName = item.Producer?.Name,
|
||||
};
|
||||
logger.LogDebug("Returning item model: {@Result}", result);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<CreateItemRespond>> CreateItem([FromBody]CreateItemRequest request)
|
||||
{
|
||||
CreateItemRespond respond = new CreateItemRespond();
|
||||
|
||||
bool ready = true;
|
||||
if (request is { ProducerName: null, ItemName: null}) return BadRequest();
|
||||
|
||||
var producer = await producerManager.FindProducerByName(request.ProducerName ?? "");
|
||||
|
||||
if (producer == null)
|
||||
{
|
||||
ready = false;
|
||||
respond.Errors["Producer"] = $"Producer {request.ProducerName} is not found";
|
||||
}
|
||||
|
||||
var listOfTags = new List<ItemCategoryTag>();
|
||||
|
||||
foreach (var itemTag in request.Tags)
|
||||
{
|
||||
var tag = await itemTagManager.GetTagByName(itemTag);
|
||||
|
||||
|
||||
if (tag == null)
|
||||
{
|
||||
ready = false;
|
||||
respond.Errors[$"Tag:{itemTag}"] = "Not found";
|
||||
continue;
|
||||
}
|
||||
|
||||
listOfTags.Add(tag);
|
||||
}
|
||||
|
||||
if (!ready)
|
||||
{
|
||||
return BadRequest(respond);
|
||||
}
|
||||
|
||||
var item = new Data.Item()
|
||||
{
|
||||
Name = request.ItemName,
|
||||
ItemCategoryTags = listOfTags,
|
||||
Producer = producer,
|
||||
};
|
||||
|
||||
var res = await itemManager.CreateAsync(item);
|
||||
|
||||
return res.IsSuccess ? Ok(item) : BadRequest(respond);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> CreateTagTree([FromBody] CreateTagTreeRequest request)
|
||||
{
|
||||
Guid id = Guid.NewGuid();
|
||||
logger.LogInformation("Request with id:{id} to create tag tree received", id);
|
||||
if (request.ItemCategoryTagsList == null || request.ItemCategoryTagsList.Count == 0)
|
||||
{
|
||||
logger.LogWarning("Request with id:{id} cannot be accepted ", id);
|
||||
return BadRequest("List cannot be empty!");
|
||||
}
|
||||
logger.LogInformation("Request with id:{id} to create item tag tree accepted", id);
|
||||
|
||||
var actor = (HttpContext.User.Identity as CaseSensitiveClaimsIdentity)?
|
||||
.Claims.Where(q => q.Type == ClaimTypes.NameIdentifier)
|
||||
.Select(q => q.Value).FirstOrDefault();
|
||||
logger.LogDebug("Actor identified: {Actor}", actor);
|
||||
|
||||
await taskManager.CreateTask(id, actor);
|
||||
logger.LogDebug("Task created with ID {TaskId}", id);
|
||||
|
||||
var kafkaMess = new TagTreeKafkaMessage()
|
||||
{
|
||||
Guid = id,
|
||||
ItemCategoryTagsList = request.ItemCategoryTagsList,
|
||||
Action = Actions.Create
|
||||
};
|
||||
logger.LogDebug("Publishing Kafka message: {@KafkaMessage}", kafkaMess);
|
||||
|
||||
_ = publishTagTreeEndpoint.Produce(kafkaMess);
|
||||
|
||||
return Accepted($"/status/{id}");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> DeleteTagList([FromBody] CreateTagTreeRequest request)
|
||||
{
|
||||
Guid id = Guid.NewGuid();
|
||||
logger.LogInformation("Request with id:{id} to delete tag list received", id);
|
||||
|
||||
if (request.ItemCategoryTagsList == null || request.ItemCategoryTagsList.Count == 0)
|
||||
{
|
||||
logger.LogWarning("Request with id:{id} cannot be accepted ", id);
|
||||
return BadRequest("List cannot be empty!");
|
||||
}
|
||||
|
||||
logger.LogInformation("Request with id:{id} to delete tag list accepted", id);
|
||||
|
||||
var actor = (HttpContext.User.Identity as CaseSensitiveClaimsIdentity)?
|
||||
.Claims.Where(q => q.Type == ClaimTypes.NameIdentifier)
|
||||
.Select(q => q.Value).FirstOrDefault();
|
||||
logger.LogDebug("Actor identified: {Actor}", actor);
|
||||
|
||||
await taskManager.CreateTask(id, actor);
|
||||
logger.LogDebug("Task created with ID {TaskId}", id);
|
||||
|
||||
var kafkaMess = new TagTreeKafkaMessage()
|
||||
{
|
||||
Guid = id,
|
||||
ItemCategoryTagsList = request.ItemCategoryTagsList,
|
||||
Action = Actions.Delete
|
||||
};
|
||||
logger.LogDebug("Publishing Kafka message: {@KafkaMessage}", kafkaMess);
|
||||
|
||||
_ = publishTagTreeEndpoint.Produce(kafkaMess);
|
||||
|
||||
return Accepted($"/status/{id}");
|
||||
}
|
||||
|
||||
[HttpGet("{root}")]
|
||||
public async Task<ActionResult<TagTreeModel>> GetTagTree([FromRoute]string root)
|
||||
{
|
||||
logger.LogInformation("GetTagTree called for root {root}", root);
|
||||
|
||||
var result = await itemTagManager.GetTagTree(root);
|
||||
logger.LogDebug("Tag tree retrieved for root {Root}: {@Result}", root, result);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
logger.LogWarning("No tag tree found for root {Root}", root);
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var returnResult = GetChild(result);
|
||||
logger.LogDebug("Returning tag tree model: {@ReturnResult}", returnResult);
|
||||
|
||||
return Ok(returnResult);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<int>> UpdateItemClaims([FromBody]UpdateItemClaimRequest request)
|
||||
{
|
||||
|
||||
if (request.ItemId == null || request.ListOfUpdatedClaims.Count == 0) return BadRequest();
|
||||
int result = 0;
|
||||
|
||||
var item = await itemManager.FindItemByIdAsync(request.ItemId);
|
||||
if (item == null) return NotFound();
|
||||
|
||||
foreach (var claim in request.ListOfUpdatedClaims)
|
||||
{
|
||||
if (claim.ClaimType == null) continue;
|
||||
|
||||
if (claim.ClaimValue == null)
|
||||
{
|
||||
var resultLocal = await itemManager.DeleteClaim(item, claim.ClaimType);
|
||||
|
||||
if (resultLocal.IsSuccess)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Failed to delete claim: {ClaimType}", claim.ClaimType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var resultLocal = await itemManager.UpdateClaim(item, new Claim(claim.ClaimType, claim.ClaimValue, claim.ClaimIssuer));
|
||||
|
||||
if (resultLocal.IsSuccess)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Failed to update claim: {ClaimType}", claim.ClaimType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result> 0 ? Ok(result) : BadRequest();
|
||||
}
|
||||
|
||||
private TagTreeModel GetChild(ItemCategoryTag model)
|
||||
{
|
||||
logger.LogDebug("Building child model for tag {TagName}", model.Name);
|
||||
var result = new TagTreeModel(){Name = model.Name};
|
||||
if (model.ListOfChildrenTag != null)
|
||||
foreach (var element in model.ListOfChildrenTag)
|
||||
{
|
||||
logger.LogDebug("Processing child tag {ChildTagName}", element.Name);
|
||||
result.Child.Add(GetChild(element));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OpenWarehouse.warehouse.api.Common.Producer;
|
||||
using OpenWarehouse.warehouse.api.Model.Producer;
|
||||
|
||||
namespace OpenWarehouse.warehouse.api.Controller;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
public class Producer(ILogger<Producer> logger, IProducerManager producerManager) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateProducer([FromBody] Model.Producer.Producer? producer)
|
||||
{
|
||||
if (producer == null)
|
||||
{
|
||||
logger.LogWarning("Received null producer in CreateProducer");
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var newProducer = new Data.Producers()
|
||||
{
|
||||
FiestLineAdress = producer.FirstLineAddress,
|
||||
SecondLineAdress = producer.SecondLineAddress,
|
||||
Name = producer.Name,
|
||||
Email = producer.Email,
|
||||
Phone = producer.PhoneNumber
|
||||
};
|
||||
|
||||
var res = await producerManager.CreateAsync(newProducer);
|
||||
|
||||
if (!res.IsSuccess)
|
||||
{
|
||||
logger.LogError("Failed to create producer: {Errors}", res.Errors);
|
||||
return BadRequest(res.Errors);
|
||||
}
|
||||
|
||||
logger.LogInformation("Producer created successfully: {ProducerName}", producer.Name);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpGet("{name}")]
|
||||
public async Task<ActionResult<Model.Producer.Producer>> GetProducer([FromRoute] string name)
|
||||
{
|
||||
logger.LogInformation("Fetching producer with name: {Name}", name);
|
||||
|
||||
var res = await producerManager.FindProducerByName(name);
|
||||
|
||||
if (res == null)
|
||||
{
|
||||
logger.LogWarning("Producer not found with name: {Name}", name);
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var processedRes = new Model.Producer.Producer
|
||||
{
|
||||
Name = res.Name,
|
||||
Email = res.Email,
|
||||
PhoneNumber = res.Phone,
|
||||
FirstLineAddress = res.FiestLineAdress,
|
||||
SecondLineAddress = res.SecondLineAdress,
|
||||
Claims = res.Claims?.Select(q => q as ClaimBase).ToList(),
|
||||
};
|
||||
|
||||
logger.LogInformation("Producer fetched successfully: {Name}", name);
|
||||
return Ok(processedRes);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<Model.Producer.Producer>>> GetProducers()
|
||||
{
|
||||
logger.LogInformation("Fetching list of producers");
|
||||
|
||||
var res = await producerManager.GetProducerList();
|
||||
|
||||
var processedRes = res.Select(producer => new Model.Producer.Producer
|
||||
{
|
||||
Name = producer.Name,
|
||||
Email = producer.Email,
|
||||
PhoneNumber = producer.Phone,
|
||||
FirstLineAddress = producer.FiestLineAdress,
|
||||
SecondLineAddress = producer.SecondLineAdress,
|
||||
Claims = producer.Claims?.Select(q => q as ClaimBase).ToList(),
|
||||
}).ToList();
|
||||
|
||||
logger.LogInformation("Fetched {Count} producers", processedRes.Count);
|
||||
return Ok(processedRes);
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
public async Task<IActionResult> DeleteProducerByName([FromBody] string name)
|
||||
{
|
||||
logger.LogInformation("Deleting producer with name: {Name}", name);
|
||||
|
||||
var res = await producerManager.DeleteProducerByName(name);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
logger.LogWarning("Failed to delete producer: {Name}", name);
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
logger.LogInformation("Deleted producer successfully: {Name}", name);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<int>> UpdateProducerClaim([FromBody] UpdateClaimRequest request)
|
||||
{
|
||||
logger.LogInformation("Updating claims for producer");
|
||||
|
||||
int result = 0;
|
||||
Producers? producers;
|
||||
|
||||
if (request.Id != null)
|
||||
{
|
||||
producers = await producerManager.FindProducerById(request.Id);
|
||||
}
|
||||
else if (request.Name != null)
|
||||
{
|
||||
producers = await producerManager.FindProducerByName(request.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Invalid request: both Id and Name are null");
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
if (producers == null)
|
||||
{
|
||||
logger.LogWarning("Producer not found during claim update");
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
foreach (var claim in request.ListOfUpdateClaim)
|
||||
{
|
||||
if (claim.ClaimType == null) continue;
|
||||
|
||||
if (claim.ClaimValue == null)
|
||||
{
|
||||
var resultOperation = await producerManager.DeleteClaim(producers, claim.ClaimType);
|
||||
|
||||
if (resultOperation.IsSuccess)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Failed to delete claim: {ClaimType}", claim.ClaimType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var resultOperation = await producerManager.UpdateClaim(producers,
|
||||
new Claim(claim.ClaimType, claim.ClaimValue, claim.ClaimIssuer));
|
||||
|
||||
if (resultOperation.IsSuccess)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Failed to update claim: {ClaimType}", claim.ClaimType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Claims updated successfully. Total updated: {Count}", result);
|
||||
return result > 0 ? Ok(result) : BadRequest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OpenWarehouse.auth.lib.Model.Service;
|
||||
using OpenWarehouse.warehouse.api.Common.DefaultServiceAccountAndRole;
|
||||
using OpenWarehouse.warehouse.api.Common.ServiceClaims;
|
||||
using OpenWarehouse.warehouse.api.Model.Tool;
|
||||
|
||||
namespace OpenWarehouse.warehouse.api.Controller;
|
||||
|
||||
[ApiController]
|
||||
[Route("[action]")]
|
||||
public class Tools(
|
||||
IConfiguration configuration,
|
||||
DefaultIdentify defaultIdentify,
|
||||
IServiceClaimsManager serviceClaimsManager) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
public Task<ActionResult<PingModel>> Ping()
|
||||
{
|
||||
return Task.FromResult<ActionResult<PingModel>>(Ok(new PingModel()));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
public async Task<ActionResult<InitialziationResultModel>> InitServiceConnectionWithAuth()
|
||||
{
|
||||
Request.Headers.TryGetValue("Authorization", out var token);
|
||||
|
||||
|
||||
var result = await defaultIdentify.SeedAsync(token.ToString());
|
||||
|
||||
var testResult = false;
|
||||
|
||||
if (result.IsSuccess || result.UserAllereadyExist)
|
||||
{
|
||||
testResult = await defaultIdentify.TestAuth(result.ServiceToken ??
|
||||
throw new ArgumentNullException(
|
||||
$"Service {result.ServiceName} token is null"));
|
||||
if (testResult)
|
||||
{
|
||||
await serviceClaimsManager.UpdateClaim(ServiceClaim.ServiceAcoountToken, result.ServiceToken);
|
||||
await serviceClaimsManager.UpdateClaim(ServiceClaim.ServiceAcoountUsername, result.ServiceUsername ??
|
||||
throw new ArgumentNullException(
|
||||
$"Service {result.ServiceName} username is null"));
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new InitialziationResultModel()
|
||||
{
|
||||
Success = result.IsSuccess,
|
||||
IsAlreadyInitialized = result.UserAllereadyExist,
|
||||
ServiceAccountName = result.ServiceName,
|
||||
TestAuthSuccess = testResult
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user