From 405327f04cfde4a7168ca51abf853e4ab34020d2 Mon Sep 17 00:00:00 2001 From: Baba Kamyljanov Date: Thu, 24 Oct 2024 16:41:53 +0800 Subject: [PATCH 1/5] removed unused functions --- .../Reactions/GetAllReactionsFunction.cs | 56 ------------ .../Reactions/GetReactionsFunction.cs | 87 ------------------ .../Functions/Reactions/ReactFunction.cs | 91 ------------------- .../Reactions/RemoveReactionFunction.cs | 77 ---------------- .../User/ConnectUserToCommentsFunction.cs | 88 ------------------ .../Functions/User/GetUserFunction.cs | 68 -------------- .../User/RemoveUserCommentsAccountFunction.cs | 68 -------------- 7 files changed, 535 deletions(-) delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs deleted file mode 100644 index 99adeb8..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class GetAllReactionsFunction(ILoggerFactory loggerFactory, RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("GetAllReactionsFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestData req, - FunctionContext executionContext) - { - _logger.LogWarning($"HTTP trigger function {nameof(GetAllReactionsFunction)} received a request."); - - var userId = req.Query["user_id"]; - - if (string.IsNullOrEmpty(userId)) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Missing or empty user_id param", - }, HttpStatusCode.BadRequest); - } - - _logger.LogInformation("Checking for bookmarks by user: {0}", userId); - var likesDislikes = await dbContext.Reactions.Query(q => q.Where(w => w.UserId == userId)); - - var likesList = likesDislikes.ToList(); - if (likesList.Count != 0) - { - return req.CreateJsonResponse(new - { - error = false, - message = "", - likesDislikedRules = likesList, - }); - } - - _logger.LogInformation($"Could not find results for user: {userId}"); - return req.CreateJsonResponse(new - { - error = true, - message = $"Could not find results for user: {userId}", - likesDislikedRules = likesList, - }, HttpStatusCode.NotFound); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs deleted file mode 100644 index aefc3da..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class GetReactionsFunction(ILoggerFactory loggerFactory, RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("GetReactionsFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - _logger.LogWarning($"HTTP trigger function {nameof(GetReactionsFunction)} received a request."); - - var ruleGuid = req.Query["rule_guid"]; - var userId = req.Query["user_id"]; - - if (ruleGuid == null) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Missing RuleGuid param", - }, HttpStatusCode.BadRequest); - } - - var likes = await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == ruleGuid)); - - var likesList = likes.ToList(); - if (!likesList.Any()) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Could not find results for rule id: " + ruleGuid, - }, HttpStatusCode.NotFound); - } - - // Group and count reactions by type - var results = likesList - .GroupBy(l => l.Type) - .Select(g => new - { - Type = g.Key, - Count = g.Count() - }).ToList(); - - ReactionType? userStatus = null; - if (string.IsNullOrEmpty(userId)) - { - return req.CreateJsonResponse(new - { - error = false, - message = "", - superLikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperLike)?.Count ?? 0, - likeCount = results.FirstOrDefault(r => r.Type == ReactionType.Like)?.Count ?? 0, - dislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.Dislike)?.Count ?? 0, - superDislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperDislike)?.Count ?? 0, - userStatus - }); - } - - var userReaction = likesList.FirstOrDefault(w => w.UserId == userId); - userStatus = userReaction?.Type; - _logger.LogInformation("Found reaction for user: '{0}' reaction: '{1}'", userId, userStatus); - - return req.CreateJsonResponse(new - { - error = false, - message = "", - superLikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperLike)?.Count ?? 0, - likeCount = results.FirstOrDefault(r => r.Type == ReactionType.Like)?.Count ?? 0, - dislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.Dislike)?.Count ?? 0, - superDislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperDislike)?.Count ?? 0, - userStatus - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs deleted file mode 100644 index c205a5c..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class ReactFunction( - ILoggerFactory loggerFactory, - RulesDbContext dbContext, - IApiAuthorization apiAuthorization) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("ReactFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - return req.CreateJsonErrorResponse(HttpStatusCode.Unauthorized); - } - - _logger.LogWarning($"HTTP trigger function {nameof(ReactFunction)} request is authorized."); - - Reaction data; - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - data = JsonConvert.DeserializeObject(requestBody); - - bool isNull = string.IsNullOrEmpty(data?.RuleGuid) || string.IsNullOrEmpty(data?.UserId) || data?.Type == null; - if (data == null || isNull) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Request body is empty", - }, HttpStatusCode.BadRequest); - } - - - var results = - await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == data.RuleGuid && w.UserId == data.UserId)); - var reactionsList = results.ToList(); - var model = reactionsList.FirstOrDefault(); - _logger.LogInformation($"reactions on same rule by same user: {reactionsList.Count()}"); - - if (model == null) - { - model = await dbContext.Reactions.Add(data); - _logger.LogInformation("Added new reaction. Id: {0}", model.Id); - } - else - { - _logger.LogInformation("Reaction already exists for user {0}", model.UserId); - - if (model.Type != data.Type) - { - model.Type = data.Type; - model = await dbContext.Reactions.Update(model); - _logger.LogInformation("Updated reaction to " + model.Type); - } - else - { - _logger.LogInformation("Reaction is the same. No change"); - } - } - - _logger.LogInformation($"User: {model.UserId}, Type: {model.Type}, Rule: {model.RuleGuid}, Id: {model.Id}"); - - return req.CreateJsonResponse(new - { - error = false, - message = "", - reaction = model.Type - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs deleted file mode 100644 index 3daf77d..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class RemoveReactionFunction( - ILoggerFactory loggerFactory, - RulesDbContext dbContext, - IApiAuthorization apiAuthorization) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("RemoveReactionFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - return req.CreateResponse(HttpStatusCode.Unauthorized); - } - - _logger.LogWarning($"HTTP trigger function {nameof(RemoveReactionFunction)} request is authorized."); - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - Reaction data = JsonConvert.DeserializeObject(requestBody); - - bool isNull = string.IsNullOrEmpty(data?.RuleGuid) || string.IsNullOrEmpty(data?.UserId) || data?.Type == null; - if (data == null || isNull) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Request body is empty", - }, HttpStatusCode.BadRequest); - } - - var results = - await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == data.RuleGuid && w.UserId == data.UserId)); - var model = results.FirstOrDefault(); - - if (model == null) - { - _logger.LogInformation("No reaction exists for User {0} and Rule {1}", data.UserId, data.RuleGuid); - return req.CreateJsonResponse(new - { - error = true, - message = "No reaction exists for this rule and user", - data.UserId, - data.RuleGuid, - }, HttpStatusCode.NotFound); - } - - await dbContext.Reactions.Delete(model); - _logger.LogInformation($"User: {model.UserId}, Rule: {model.RuleGuid}, Id: {model.Id}"); - - return req.CreateJsonResponse(new - { - error = false, - message = "" - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs b/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs deleted file mode 100644 index 7dc0f58..0000000 --- a/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; -using DomainUser = SSW.Rules.AzFuncs.Domain.User; - -namespace SSW.Rules.AzFuncs.Functions.User; - -public class ConnectUserCommentsFunction( - ILoggerFactory loggerFactory, - RulesDbContext dbContext, - IApiAuthorization apiAuthorization) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("ConnectUserCommentsFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - _logger.LogWarning($"HTTP trigger function {nameof(ConnectUserCommentsFunction)} received a request."); - - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - return req.CreateResponse(HttpStatusCode.Unauthorized); - } - - _logger.LogWarning($"HTTP trigger function {nameof(ConnectUserCommentsFunction)} request is authorized."); - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - var data = JsonConvert.DeserializeObject(requestBody); - - if (data == null || string.IsNullOrEmpty(data.CommentsUserId) || string.IsNullOrEmpty(data.UserId)) - { - return req.CreateJsonResponse( - new { message = "Request body is empty or is missing CommentsUserId or UserId fields" }, - HttpStatusCode.BadRequest); - } - - - var existingUser = await dbContext.Users.Query(q => q.Where(w => w.UserId == data.UserId)); - var user = existingUser.FirstOrDefault(); - - if (user == null) - { - await dbContext.Users.Add(data); - return req.CreateResponse(HttpStatusCode.OK); - } - - if (user.CommentsUserId == data.CommentsUserId) - { - return req.CreateJsonResponse(new { message = "User already has the same comments account associated" }, - HttpStatusCode.OK); - } - - if (!string.IsNullOrEmpty(user.CommentsUserId)) - { - return req.CreateJsonResponse(new { message = "Different comments account already connected" }, - HttpStatusCode.Conflict); - } - - var existingCommentsId = - await dbContext.Users.Query(q => q.Where(w => w.CommentsUserId == data.CommentsUserId)); - - if (existingCommentsId.Any()) - { - return req.CreateJsonResponse( - new { message = "This comments account is already being used by another user" }, - HttpStatusCode.Conflict); - } - - user.CommentsUserId = data.CommentsUserId; - await dbContext.Users.Update(user); - - return req.CreateResponse(HttpStatusCode.OK); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs b/SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs deleted file mode 100644 index 5051e65..0000000 --- a/SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; -using DomainUser = SSW.Rules.AzFuncs.Domain.User; - -namespace SSW.Rules.AzFuncs.Functions.User; - -public class GetUserFunction( - ILoggerFactory loggerFactory, - IApiAuthorization apiAuthorization, - RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("GetUserFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - var unauthorizedResponse = req.CreateResponse(HttpStatusCode.Unauthorized); - return unauthorizedResponse; - } - - _logger.LogInformation($"HTTP trigger function {nameof(GetUserFunction)} request is authorized."); - - var userId = req.Query["user_id"]; - - if (string.IsNullOrEmpty(userId)) - { - return req.CreateJsonResponse(new - { - message = "Missing or empty user_id param", - }, HttpStatusCode.BadRequest); - } - - var result = await dbContext.Users.Query(q => q.Where(w => w.UserId == userId)); - var user = result.FirstOrDefault(); - - if (user == null) - { - _logger.LogInformation($"Could not find results for user: {userId}"); - return req.CreateJsonResponse(new - { - message = "User " + userId + " was not found", - }, HttpStatusCode.BadRequest); - } - - bool commentsConnected = !string.IsNullOrEmpty(user?.CommentsUserId); - - return req.CreateJsonResponse(new - { - user, commentsConnected, - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs b/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs deleted file mode 100644 index 2560659..0000000 --- a/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; -using DomainUser = SSW.Rules.AzFuncs.Domain.User; - -namespace SSW.Rules.AzFuncs.Functions.User; - -public class RemoveUserCommentsAccountFunction( - ILoggerFactory loggerFactory, - IApiAuthorization apiAuthorization, - RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("RemoveUserCommentsAccountFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - var unauthorizedResponse = req.CreateResponse(HttpStatusCode.Unauthorized); - return unauthorizedResponse; - } - - _logger.LogInformation( - $"HTTP trigger function {nameof(RemoveUserCommentsAccountFunction)} request is authorized."); - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - DomainUser data = JsonConvert.DeserializeObject(requestBody); - - if (data == null || string.IsNullOrEmpty(data?.UserId)) - { - return req.CreateJsonResponse(new - { - message = "Request body is empty or UserId is missing", - }, HttpStatusCode.BadRequest); - } - - var user = await dbContext.Users.Query(q => q.Where(w => w.UserId == data.UserId)); - var model = user.FirstOrDefault(); - - if (model == null) - { - return req.CreateJsonResponse(new - { - message = "User does not exist" - }, HttpStatusCode.BadRequest); - } - - model.CommentsUserId = null; - await dbContext.Users.Update(model); - - return req.CreateResponse(HttpStatusCode.OK); - } -} \ No newline at end of file From 7b08224e7793541fb2bd26d610a102d86d712b6b Mon Sep 17 00:00:00 2001 From: Baba Kamyljanov Date: Thu, 24 Oct 2024 16:43:58 +0800 Subject: [PATCH 2/5] Revert "removed unused functions" This reverts commit 405327f04cfde4a7168ca51abf853e4ab34020d2. --- .../Reactions/GetAllReactionsFunction.cs | 56 ++++++++++++ .../Reactions/GetReactionsFunction.cs | 87 ++++++++++++++++++ .../Functions/Reactions/ReactFunction.cs | 91 +++++++++++++++++++ .../Reactions/RemoveReactionFunction.cs | 77 ++++++++++++++++ .../User/ConnectUserToCommentsFunction.cs | 88 ++++++++++++++++++ .../Functions/User/GetUserFunction.cs | 68 ++++++++++++++ .../User/RemoveUserCommentsAccountFunction.cs | 68 ++++++++++++++ 7 files changed, 535 insertions(+) create mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs create mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs create mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs create mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs create mode 100644 SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs create mode 100644 SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs create mode 100644 SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs new file mode 100644 index 0000000..99adeb8 --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs @@ -0,0 +1,56 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using SSW.Rules.AzFuncs.Domain; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; + +namespace SSW.Rules.AzFuncs.Functions.Reactions; + +public class GetAllReactionsFunction(ILoggerFactory loggerFactory, RulesDbContext dbContext) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("GetAllReactionsFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestData req, + FunctionContext executionContext) + { + _logger.LogWarning($"HTTP trigger function {nameof(GetAllReactionsFunction)} received a request."); + + var userId = req.Query["user_id"]; + + if (string.IsNullOrEmpty(userId)) + { + return req.CreateJsonResponse(new + { + error = true, + message = "Missing or empty user_id param", + }, HttpStatusCode.BadRequest); + } + + _logger.LogInformation("Checking for bookmarks by user: {0}", userId); + var likesDislikes = await dbContext.Reactions.Query(q => q.Where(w => w.UserId == userId)); + + var likesList = likesDislikes.ToList(); + if (likesList.Count != 0) + { + return req.CreateJsonResponse(new + { + error = false, + message = "", + likesDislikedRules = likesList, + }); + } + + _logger.LogInformation($"Could not find results for user: {userId}"); + return req.CreateJsonResponse(new + { + error = true, + message = $"Could not find results for user: {userId}", + likesDislikedRules = likesList, + }, HttpStatusCode.NotFound); + } +} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs new file mode 100644 index 0000000..aefc3da --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs @@ -0,0 +1,87 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using SSW.Rules.AzFuncs.Domain; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; + +namespace SSW.Rules.AzFuncs.Functions.Reactions; + +public class GetReactionsFunction(ILoggerFactory loggerFactory, RulesDbContext dbContext) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("GetReactionsFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] + HttpRequestData req, + FunctionContext executionContext) + { + _logger.LogWarning($"HTTP trigger function {nameof(GetReactionsFunction)} received a request."); + + var ruleGuid = req.Query["rule_guid"]; + var userId = req.Query["user_id"]; + + if (ruleGuid == null) + { + return req.CreateJsonResponse(new + { + error = true, + message = "Missing RuleGuid param", + }, HttpStatusCode.BadRequest); + } + + var likes = await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == ruleGuid)); + + var likesList = likes.ToList(); + if (!likesList.Any()) + { + return req.CreateJsonResponse(new + { + error = true, + message = "Could not find results for rule id: " + ruleGuid, + }, HttpStatusCode.NotFound); + } + + // Group and count reactions by type + var results = likesList + .GroupBy(l => l.Type) + .Select(g => new + { + Type = g.Key, + Count = g.Count() + }).ToList(); + + ReactionType? userStatus = null; + if (string.IsNullOrEmpty(userId)) + { + return req.CreateJsonResponse(new + { + error = false, + message = "", + superLikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperLike)?.Count ?? 0, + likeCount = results.FirstOrDefault(r => r.Type == ReactionType.Like)?.Count ?? 0, + dislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.Dislike)?.Count ?? 0, + superDislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperDislike)?.Count ?? 0, + userStatus + }); + } + + var userReaction = likesList.FirstOrDefault(w => w.UserId == userId); + userStatus = userReaction?.Type; + _logger.LogInformation("Found reaction for user: '{0}' reaction: '{1}'", userId, userStatus); + + return req.CreateJsonResponse(new + { + error = false, + message = "", + superLikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperLike)?.Count ?? 0, + likeCount = results.FirstOrDefault(r => r.Type == ReactionType.Like)?.Count ?? 0, + dislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.Dislike)?.Count ?? 0, + superDislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperDislike)?.Count ?? 0, + userStatus + }); + } +} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs new file mode 100644 index 0000000..c205a5c --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs @@ -0,0 +1,91 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using OidcApiAuthorization.Abstractions; +using OidcApiAuthorization.Models; +using SSW.Rules.AzFuncs.Domain; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; + +namespace SSW.Rules.AzFuncs.Functions.Reactions; + +public class ReactFunction( + ILoggerFactory loggerFactory, + RulesDbContext dbContext, + IApiAuthorization apiAuthorization) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("ReactFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] + HttpRequestData req, + FunctionContext executionContext) + { + ApiAuthorizationResult authorizationResult = + await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); + + if (authorizationResult.Failed) + { + _logger.LogWarning(authorizationResult.FailureReason); + return req.CreateJsonErrorResponse(HttpStatusCode.Unauthorized); + } + + _logger.LogWarning($"HTTP trigger function {nameof(ReactFunction)} request is authorized."); + + Reaction data; + + string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); + data = JsonConvert.DeserializeObject(requestBody); + + bool isNull = string.IsNullOrEmpty(data?.RuleGuid) || string.IsNullOrEmpty(data?.UserId) || data?.Type == null; + if (data == null || isNull) + { + return req.CreateJsonResponse(new + { + error = true, + message = "Request body is empty", + }, HttpStatusCode.BadRequest); + } + + + var results = + await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == data.RuleGuid && w.UserId == data.UserId)); + var reactionsList = results.ToList(); + var model = reactionsList.FirstOrDefault(); + _logger.LogInformation($"reactions on same rule by same user: {reactionsList.Count()}"); + + if (model == null) + { + model = await dbContext.Reactions.Add(data); + _logger.LogInformation("Added new reaction. Id: {0}", model.Id); + } + else + { + _logger.LogInformation("Reaction already exists for user {0}", model.UserId); + + if (model.Type != data.Type) + { + model.Type = data.Type; + model = await dbContext.Reactions.Update(model); + _logger.LogInformation("Updated reaction to " + model.Type); + } + else + { + _logger.LogInformation("Reaction is the same. No change"); + } + } + + _logger.LogInformation($"User: {model.UserId}, Type: {model.Type}, Rule: {model.RuleGuid}, Id: {model.Id}"); + + return req.CreateJsonResponse(new + { + error = false, + message = "", + reaction = model.Type + }); + } +} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs new file mode 100644 index 0000000..3daf77d --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs @@ -0,0 +1,77 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using OidcApiAuthorization.Abstractions; +using OidcApiAuthorization.Models; +using SSW.Rules.AzFuncs.Domain; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; + +namespace SSW.Rules.AzFuncs.Functions.Reactions; + +public class RemoveReactionFunction( + ILoggerFactory loggerFactory, + RulesDbContext dbContext, + IApiAuthorization apiAuthorization) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("RemoveReactionFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] + HttpRequestData req, + FunctionContext executionContext) + { + ApiAuthorizationResult authorizationResult = + await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); + + if (authorizationResult.Failed) + { + _logger.LogWarning(authorizationResult.FailureReason); + return req.CreateResponse(HttpStatusCode.Unauthorized); + } + + _logger.LogWarning($"HTTP trigger function {nameof(RemoveReactionFunction)} request is authorized."); + + string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); + Reaction data = JsonConvert.DeserializeObject(requestBody); + + bool isNull = string.IsNullOrEmpty(data?.RuleGuid) || string.IsNullOrEmpty(data?.UserId) || data?.Type == null; + if (data == null || isNull) + { + return req.CreateJsonResponse(new + { + error = true, + message = "Request body is empty", + }, HttpStatusCode.BadRequest); + } + + var results = + await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == data.RuleGuid && w.UserId == data.UserId)); + var model = results.FirstOrDefault(); + + if (model == null) + { + _logger.LogInformation("No reaction exists for User {0} and Rule {1}", data.UserId, data.RuleGuid); + return req.CreateJsonResponse(new + { + error = true, + message = "No reaction exists for this rule and user", + data.UserId, + data.RuleGuid, + }, HttpStatusCode.NotFound); + } + + await dbContext.Reactions.Delete(model); + _logger.LogInformation($"User: {model.UserId}, Rule: {model.RuleGuid}, Id: {model.Id}"); + + return req.CreateJsonResponse(new + { + error = false, + message = "" + }); + } +} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs b/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs new file mode 100644 index 0000000..7dc0f58 --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs @@ -0,0 +1,88 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using OidcApiAuthorization.Abstractions; +using OidcApiAuthorization.Models; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; +using DomainUser = SSW.Rules.AzFuncs.Domain.User; + +namespace SSW.Rules.AzFuncs.Functions.User; + +public class ConnectUserCommentsFunction( + ILoggerFactory loggerFactory, + RulesDbContext dbContext, + IApiAuthorization apiAuthorization) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("ConnectUserCommentsFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] + HttpRequestData req, + FunctionContext executionContext) + { + _logger.LogWarning($"HTTP trigger function {nameof(ConnectUserCommentsFunction)} received a request."); + + ApiAuthorizationResult authorizationResult = + await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); + + if (authorizationResult.Failed) + { + _logger.LogWarning(authorizationResult.FailureReason); + return req.CreateResponse(HttpStatusCode.Unauthorized); + } + + _logger.LogWarning($"HTTP trigger function {nameof(ConnectUserCommentsFunction)} request is authorized."); + + string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); + var data = JsonConvert.DeserializeObject(requestBody); + + if (data == null || string.IsNullOrEmpty(data.CommentsUserId) || string.IsNullOrEmpty(data.UserId)) + { + return req.CreateJsonResponse( + new { message = "Request body is empty or is missing CommentsUserId or UserId fields" }, + HttpStatusCode.BadRequest); + } + + + var existingUser = await dbContext.Users.Query(q => q.Where(w => w.UserId == data.UserId)); + var user = existingUser.FirstOrDefault(); + + if (user == null) + { + await dbContext.Users.Add(data); + return req.CreateResponse(HttpStatusCode.OK); + } + + if (user.CommentsUserId == data.CommentsUserId) + { + return req.CreateJsonResponse(new { message = "User already has the same comments account associated" }, + HttpStatusCode.OK); + } + + if (!string.IsNullOrEmpty(user.CommentsUserId)) + { + return req.CreateJsonResponse(new { message = "Different comments account already connected" }, + HttpStatusCode.Conflict); + } + + var existingCommentsId = + await dbContext.Users.Query(q => q.Where(w => w.CommentsUserId == data.CommentsUserId)); + + if (existingCommentsId.Any()) + { + return req.CreateJsonResponse( + new { message = "This comments account is already being used by another user" }, + HttpStatusCode.Conflict); + } + + user.CommentsUserId = data.CommentsUserId; + await dbContext.Users.Update(user); + + return req.CreateResponse(HttpStatusCode.OK); + } +} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs b/SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs new file mode 100644 index 0000000..5051e65 --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/User/GetUserFunction.cs @@ -0,0 +1,68 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using OidcApiAuthorization.Abstractions; +using OidcApiAuthorization.Models; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; +using DomainUser = SSW.Rules.AzFuncs.Domain.User; + +namespace SSW.Rules.AzFuncs.Functions.User; + +public class GetUserFunction( + ILoggerFactory loggerFactory, + IApiAuthorization apiAuthorization, + RulesDbContext dbContext) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("GetUserFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, Route = null)] + HttpRequestData req, + FunctionContext executionContext) + { + ApiAuthorizationResult authorizationResult = + await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); + + if (authorizationResult.Failed) + { + _logger.LogWarning(authorizationResult.FailureReason); + var unauthorizedResponse = req.CreateResponse(HttpStatusCode.Unauthorized); + return unauthorizedResponse; + } + + _logger.LogInformation($"HTTP trigger function {nameof(GetUserFunction)} request is authorized."); + + var userId = req.Query["user_id"]; + + if (string.IsNullOrEmpty(userId)) + { + return req.CreateJsonResponse(new + { + message = "Missing or empty user_id param", + }, HttpStatusCode.BadRequest); + } + + var result = await dbContext.Users.Query(q => q.Where(w => w.UserId == userId)); + var user = result.FirstOrDefault(); + + if (user == null) + { + _logger.LogInformation($"Could not find results for user: {userId}"); + return req.CreateJsonResponse(new + { + message = "User " + userId + " was not found", + }, HttpStatusCode.BadRequest); + } + + bool commentsConnected = !string.IsNullOrEmpty(user?.CommentsUserId); + + return req.CreateJsonResponse(new + { + user, commentsConnected, + }); + } +} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs b/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs new file mode 100644 index 0000000..2560659 --- /dev/null +++ b/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs @@ -0,0 +1,68 @@ +using System.Net; +using AzureGems.CosmosDB; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using OidcApiAuthorization.Abstractions; +using OidcApiAuthorization.Models; +using SSW.Rules.AzFuncs.helpers; +using SSW.Rules.AzFuncs.Persistence; +using DomainUser = SSW.Rules.AzFuncs.Domain.User; + +namespace SSW.Rules.AzFuncs.Functions.User; + +public class RemoveUserCommentsAccountFunction( + ILoggerFactory loggerFactory, + IApiAuthorization apiAuthorization, + RulesDbContext dbContext) +{ + private readonly ILogger _logger = loggerFactory.CreateLogger(); + + [Function("RemoveUserCommentsAccountFunction")] + public async Task Run( + [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] + HttpRequestData req, + FunctionContext executionContext) + { + ApiAuthorizationResult authorizationResult = + await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); + + if (authorizationResult.Failed) + { + _logger.LogWarning(authorizationResult.FailureReason); + var unauthorizedResponse = req.CreateResponse(HttpStatusCode.Unauthorized); + return unauthorizedResponse; + } + + _logger.LogInformation( + $"HTTP trigger function {nameof(RemoveUserCommentsAccountFunction)} request is authorized."); + + string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); + DomainUser data = JsonConvert.DeserializeObject(requestBody); + + if (data == null || string.IsNullOrEmpty(data?.UserId)) + { + return req.CreateJsonResponse(new + { + message = "Request body is empty or UserId is missing", + }, HttpStatusCode.BadRequest); + } + + var user = await dbContext.Users.Query(q => q.Where(w => w.UserId == data.UserId)); + var model = user.FirstOrDefault(); + + if (model == null) + { + return req.CreateJsonResponse(new + { + message = "User does not exist" + }, HttpStatusCode.BadRequest); + } + + model.CommentsUserId = null; + await dbContext.Users.Update(model); + + return req.CreateResponse(HttpStatusCode.OK); + } +} \ No newline at end of file From cabf107cbf08e2299c538439c65de886d8c3b8a6 Mon Sep 17 00:00:00 2001 From: Baba Kamyljanov Date: Thu, 24 Oct 2024 17:08:46 +0800 Subject: [PATCH 3/5] deleted functions --- .../Reactions/GetAllReactionsFunction.cs | 56 ------------ .../Reactions/GetReactionsFunction.cs | 87 ------------------ .../Functions/Reactions/ReactFunction.cs | 91 ------------------- .../Reactions/RemoveReactionFunction.cs | 77 ---------------- .../User/ConnectUserToCommentsFunction.cs | 88 ------------------ .../User/RemoveUserCommentsAccountFunction.cs | 68 -------------- 6 files changed, 467 deletions(-) delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs delete mode 100644 SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs deleted file mode 100644 index 99adeb8..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/GetAllReactionsFunction.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class GetAllReactionsFunction(ILoggerFactory loggerFactory, RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("GetAllReactionsFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestData req, - FunctionContext executionContext) - { - _logger.LogWarning($"HTTP trigger function {nameof(GetAllReactionsFunction)} received a request."); - - var userId = req.Query["user_id"]; - - if (string.IsNullOrEmpty(userId)) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Missing or empty user_id param", - }, HttpStatusCode.BadRequest); - } - - _logger.LogInformation("Checking for bookmarks by user: {0}", userId); - var likesDislikes = await dbContext.Reactions.Query(q => q.Where(w => w.UserId == userId)); - - var likesList = likesDislikes.ToList(); - if (likesList.Count != 0) - { - return req.CreateJsonResponse(new - { - error = false, - message = "", - likesDislikedRules = likesList, - }); - } - - _logger.LogInformation($"Could not find results for user: {userId}"); - return req.CreateJsonResponse(new - { - error = true, - message = $"Could not find results for user: {userId}", - likesDislikedRules = likesList, - }, HttpStatusCode.NotFound); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs deleted file mode 100644 index aefc3da..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/GetReactionsFunction.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class GetReactionsFunction(ILoggerFactory loggerFactory, RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("GetReactionsFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - _logger.LogWarning($"HTTP trigger function {nameof(GetReactionsFunction)} received a request."); - - var ruleGuid = req.Query["rule_guid"]; - var userId = req.Query["user_id"]; - - if (ruleGuid == null) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Missing RuleGuid param", - }, HttpStatusCode.BadRequest); - } - - var likes = await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == ruleGuid)); - - var likesList = likes.ToList(); - if (!likesList.Any()) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Could not find results for rule id: " + ruleGuid, - }, HttpStatusCode.NotFound); - } - - // Group and count reactions by type - var results = likesList - .GroupBy(l => l.Type) - .Select(g => new - { - Type = g.Key, - Count = g.Count() - }).ToList(); - - ReactionType? userStatus = null; - if (string.IsNullOrEmpty(userId)) - { - return req.CreateJsonResponse(new - { - error = false, - message = "", - superLikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperLike)?.Count ?? 0, - likeCount = results.FirstOrDefault(r => r.Type == ReactionType.Like)?.Count ?? 0, - dislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.Dislike)?.Count ?? 0, - superDislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperDislike)?.Count ?? 0, - userStatus - }); - } - - var userReaction = likesList.FirstOrDefault(w => w.UserId == userId); - userStatus = userReaction?.Type; - _logger.LogInformation("Found reaction for user: '{0}' reaction: '{1}'", userId, userStatus); - - return req.CreateJsonResponse(new - { - error = false, - message = "", - superLikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperLike)?.Count ?? 0, - likeCount = results.FirstOrDefault(r => r.Type == ReactionType.Like)?.Count ?? 0, - dislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.Dislike)?.Count ?? 0, - superDislikeCount = results.FirstOrDefault(r => r.Type == ReactionType.SuperDislike)?.Count ?? 0, - userStatus - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs deleted file mode 100644 index c205a5c..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/ReactFunction.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class ReactFunction( - ILoggerFactory loggerFactory, - RulesDbContext dbContext, - IApiAuthorization apiAuthorization) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("ReactFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - return req.CreateJsonErrorResponse(HttpStatusCode.Unauthorized); - } - - _logger.LogWarning($"HTTP trigger function {nameof(ReactFunction)} request is authorized."); - - Reaction data; - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - data = JsonConvert.DeserializeObject(requestBody); - - bool isNull = string.IsNullOrEmpty(data?.RuleGuid) || string.IsNullOrEmpty(data?.UserId) || data?.Type == null; - if (data == null || isNull) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Request body is empty", - }, HttpStatusCode.BadRequest); - } - - - var results = - await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == data.RuleGuid && w.UserId == data.UserId)); - var reactionsList = results.ToList(); - var model = reactionsList.FirstOrDefault(); - _logger.LogInformation($"reactions on same rule by same user: {reactionsList.Count()}"); - - if (model == null) - { - model = await dbContext.Reactions.Add(data); - _logger.LogInformation("Added new reaction. Id: {0}", model.Id); - } - else - { - _logger.LogInformation("Reaction already exists for user {0}", model.UserId); - - if (model.Type != data.Type) - { - model.Type = data.Type; - model = await dbContext.Reactions.Update(model); - _logger.LogInformation("Updated reaction to " + model.Type); - } - else - { - _logger.LogInformation("Reaction is the same. No change"); - } - } - - _logger.LogInformation($"User: {model.UserId}, Type: {model.Type}, Rule: {model.RuleGuid}, Id: {model.Id}"); - - return req.CreateJsonResponse(new - { - error = false, - message = "", - reaction = model.Type - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs b/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs deleted file mode 100644 index 3daf77d..0000000 --- a/SSW.Rules.AzFuncs/Functions/Reactions/RemoveReactionFunction.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.Domain; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; - -namespace SSW.Rules.AzFuncs.Functions.Reactions; - -public class RemoveReactionFunction( - ILoggerFactory loggerFactory, - RulesDbContext dbContext, - IApiAuthorization apiAuthorization) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("RemoveReactionFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - return req.CreateResponse(HttpStatusCode.Unauthorized); - } - - _logger.LogWarning($"HTTP trigger function {nameof(RemoveReactionFunction)} request is authorized."); - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - Reaction data = JsonConvert.DeserializeObject(requestBody); - - bool isNull = string.IsNullOrEmpty(data?.RuleGuid) || string.IsNullOrEmpty(data?.UserId) || data?.Type == null; - if (data == null || isNull) - { - return req.CreateJsonResponse(new - { - error = true, - message = "Request body is empty", - }, HttpStatusCode.BadRequest); - } - - var results = - await dbContext.Reactions.Query(q => q.Where(w => w.RuleGuid == data.RuleGuid && w.UserId == data.UserId)); - var model = results.FirstOrDefault(); - - if (model == null) - { - _logger.LogInformation("No reaction exists for User {0} and Rule {1}", data.UserId, data.RuleGuid); - return req.CreateJsonResponse(new - { - error = true, - message = "No reaction exists for this rule and user", - data.UserId, - data.RuleGuid, - }, HttpStatusCode.NotFound); - } - - await dbContext.Reactions.Delete(model); - _logger.LogInformation($"User: {model.UserId}, Rule: {model.RuleGuid}, Id: {model.Id}"); - - return req.CreateJsonResponse(new - { - error = false, - message = "" - }); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs b/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs deleted file mode 100644 index 7dc0f58..0000000 --- a/SSW.Rules.AzFuncs/Functions/User/ConnectUserToCommentsFunction.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; -using DomainUser = SSW.Rules.AzFuncs.Domain.User; - -namespace SSW.Rules.AzFuncs.Functions.User; - -public class ConnectUserCommentsFunction( - ILoggerFactory loggerFactory, - RulesDbContext dbContext, - IApiAuthorization apiAuthorization) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("ConnectUserCommentsFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - _logger.LogWarning($"HTTP trigger function {nameof(ConnectUserCommentsFunction)} received a request."); - - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - return req.CreateResponse(HttpStatusCode.Unauthorized); - } - - _logger.LogWarning($"HTTP trigger function {nameof(ConnectUserCommentsFunction)} request is authorized."); - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - var data = JsonConvert.DeserializeObject(requestBody); - - if (data == null || string.IsNullOrEmpty(data.CommentsUserId) || string.IsNullOrEmpty(data.UserId)) - { - return req.CreateJsonResponse( - new { message = "Request body is empty or is missing CommentsUserId or UserId fields" }, - HttpStatusCode.BadRequest); - } - - - var existingUser = await dbContext.Users.Query(q => q.Where(w => w.UserId == data.UserId)); - var user = existingUser.FirstOrDefault(); - - if (user == null) - { - await dbContext.Users.Add(data); - return req.CreateResponse(HttpStatusCode.OK); - } - - if (user.CommentsUserId == data.CommentsUserId) - { - return req.CreateJsonResponse(new { message = "User already has the same comments account associated" }, - HttpStatusCode.OK); - } - - if (!string.IsNullOrEmpty(user.CommentsUserId)) - { - return req.CreateJsonResponse(new { message = "Different comments account already connected" }, - HttpStatusCode.Conflict); - } - - var existingCommentsId = - await dbContext.Users.Query(q => q.Where(w => w.CommentsUserId == data.CommentsUserId)); - - if (existingCommentsId.Any()) - { - return req.CreateJsonResponse( - new { message = "This comments account is already being used by another user" }, - HttpStatusCode.Conflict); - } - - user.CommentsUserId = data.CommentsUserId; - await dbContext.Users.Update(user); - - return req.CreateResponse(HttpStatusCode.OK); - } -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs b/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs deleted file mode 100644 index 2560659..0000000 --- a/SSW.Rules.AzFuncs/Functions/User/RemoveUserCommentsAccountFunction.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Net; -using AzureGems.CosmosDB; -using Microsoft.Azure.Functions.Worker; -using Microsoft.Azure.Functions.Worker.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using OidcApiAuthorization.Abstractions; -using OidcApiAuthorization.Models; -using SSW.Rules.AzFuncs.helpers; -using SSW.Rules.AzFuncs.Persistence; -using DomainUser = SSW.Rules.AzFuncs.Domain.User; - -namespace SSW.Rules.AzFuncs.Functions.User; - -public class RemoveUserCommentsAccountFunction( - ILoggerFactory loggerFactory, - IApiAuthorization apiAuthorization, - RulesDbContext dbContext) -{ - private readonly ILogger _logger = loggerFactory.CreateLogger(); - - [Function("RemoveUserCommentsAccountFunction")] - public async Task Run( - [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] - HttpRequestData req, - FunctionContext executionContext) - { - ApiAuthorizationResult authorizationResult = - await apiAuthorization.AuthorizeAsync(Converters.ConvertToIHeaderDictionary(req.Headers)); - - if (authorizationResult.Failed) - { - _logger.LogWarning(authorizationResult.FailureReason); - var unauthorizedResponse = req.CreateResponse(HttpStatusCode.Unauthorized); - return unauthorizedResponse; - } - - _logger.LogInformation( - $"HTTP trigger function {nameof(RemoveUserCommentsAccountFunction)} request is authorized."); - - string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); - DomainUser data = JsonConvert.DeserializeObject(requestBody); - - if (data == null || string.IsNullOrEmpty(data?.UserId)) - { - return req.CreateJsonResponse(new - { - message = "Request body is empty or UserId is missing", - }, HttpStatusCode.BadRequest); - } - - var user = await dbContext.Users.Query(q => q.Where(w => w.UserId == data.UserId)); - var model = user.FirstOrDefault(); - - if (model == null) - { - return req.CreateJsonResponse(new - { - message = "User does not exist" - }, HttpStatusCode.BadRequest); - } - - model.CommentsUserId = null; - await dbContext.Users.Update(model); - - return req.CreateResponse(HttpStatusCode.OK); - } -} \ No newline at end of file From 162e70dc2d13b6cca052dd272e46475e7ed6f9e9 Mon Sep 17 00:00:00 2001 From: Baba Kamyljanov Date: Thu, 24 Oct 2024 17:09:12 +0800 Subject: [PATCH 4/5] deleted reactions code --- SSW.Rules.AzFuncs/Domain/Reaction.cs | 18 ------------------ .../Functions/Health/HealthCheckFunction.cs | 11 +---------- .../Persistence/RulesDbContext.cs | 1 - SSW.Rules.AzFuncs/Program.cs | 2 -- 4 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 SSW.Rules.AzFuncs/Domain/Reaction.cs diff --git a/SSW.Rules.AzFuncs/Domain/Reaction.cs b/SSW.Rules.AzFuncs/Domain/Reaction.cs deleted file mode 100644 index dab1c5c..0000000 --- a/SSW.Rules.AzFuncs/Domain/Reaction.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AzureGems.Repository.Abstractions; - -namespace SSW.Rules.AzFuncs.Domain; - -public class Reaction : BaseEntity -{ - public ReactionType Type { get; set; } - public string RuleGuid { get; set; } - public string UserId { get; set; } -} - -public enum ReactionType -{ - SuperDislike, - Dislike, - Like, - SuperLike, -} \ No newline at end of file diff --git a/SSW.Rules.AzFuncs/Functions/Health/HealthCheckFunction.cs b/SSW.Rules.AzFuncs/Functions/Health/HealthCheckFunction.cs index d3a7049..022a738 100644 --- a/SSW.Rules.AzFuncs/Functions/Health/HealthCheckFunction.cs +++ b/SSW.Rules.AzFuncs/Functions/Health/HealthCheckFunction.cs @@ -1,5 +1,3 @@ -using System.Net; -using AzureGems.CosmosDB; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; @@ -27,13 +25,6 @@ public async Task Run( _logger.LogWarning($"HTTP trigger function {nameof(HealthCheckFunction)} received a request."); HealthCheckResult result = await apiAuthorization.HealthCheckAsync(); - var reactionEntity = await dbContext.Reactions.Add(new Reaction - { - Type = ReactionType.Like, - RuleGuid = "exampleRule123", - UserId = "exampleUser123", - Discriminator = typeof(Reaction).FullName - }); var bookmarkEntity = await dbContext.Bookmarks.Add(new Bookmark { @@ -49,7 +40,7 @@ public async Task Run( Discriminator = typeof(Domain.SecretContent).FullName }); - if (result.IsHealthy && reactionEntity != null && bookmarkEntity != null && secretContentEntity != null) + if (result.IsHealthy && bookmarkEntity != null && secretContentEntity != null) { _logger.LogWarning($"{nameof(HealthCheckFunction)} health check OK."); } diff --git a/SSW.Rules.AzFuncs/Persistence/RulesDbContext.cs b/SSW.Rules.AzFuncs/Persistence/RulesDbContext.cs index bea36db..58dbdf1 100644 --- a/SSW.Rules.AzFuncs/Persistence/RulesDbContext.cs +++ b/SSW.Rules.AzFuncs/Persistence/RulesDbContext.cs @@ -5,7 +5,6 @@ namespace SSW.Rules.AzFuncs.Persistence; public class RulesDbContext : CosmosContext { - public IRepository Reactions { get; set; } public IRepository Bookmarks { get; set; } public IRepository SecretContents { get; set; } public IRepository Users { get; set; } diff --git a/SSW.Rules.AzFuncs/Program.cs b/SSW.Rules.AzFuncs/Program.cs index 532e435..41cea6a 100644 --- a/SSW.Rules.AzFuncs/Program.cs +++ b/SSW.Rules.AzFuncs/Program.cs @@ -8,7 +8,6 @@ using OidcApiAuthorization; using SSW.Rules.AzFuncs.Domain; using SSW.Rules.AzFuncs.Persistence; -using Reaction = SSW.Rules.AzFuncs.Domain.Reaction; using User = SSW.Rules.AzFuncs.Domain.User; var configurationRoot = new ConfigurationBuilder() @@ -40,7 +39,6 @@ .WithSharedThroughput(400) .WithContainerConfig(c => { - c.AddContainer(containerId: nameof(Reaction), partitionKeyPath: "/id"); c.AddContainer(containerId: nameof(Bookmark), partitionKeyPath: "/id"); c.AddContainer(containerId: nameof(SecretContent), partitionKeyPath: "/id"); c.AddContainer(containerId: nameof(User), partitionKeyPath: "/id"); From 42041ae5f23488fb1e8c85395daf8fb5b47d6da2 Mon Sep 17 00:00:00 2001 From: Baba Kamyljanov Date: Thu, 24 Oct 2024 17:09:20 +0800 Subject: [PATCH 5/5] cleaned up docs --- .../docs/Functions/Functions.http | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/SSW.Rules.AzFuncs/docs/Functions/Functions.http b/SSW.Rules.AzFuncs/docs/Functions/Functions.http index b2143ea..c7fa72d 100644 --- a/SSW.Rules.AzFuncs/docs/Functions/Functions.http +++ b/SSW.Rules.AzFuncs/docs/Functions/Functions.http @@ -16,38 +16,6 @@ GET {{BaseApiUrl}}/GenerateHistoryFileFunction # History - SyncCommitHash GET {{BaseApiUrl}}/GetHistorySyncCommitHash -### -# Reactions - ReactFunction -POST {{BaseApiUrl}}/ReactFunction -Content-Type: application/json -Authorization: Bearer {{Token}} - -{ - "type": 3, - "ruleGuid": "{{RuleGuid}}", - "userId": "{{UserId}}" -} - -### -# Reactions - RemoveReactionFunction -POST {{BaseApiUrl}}/RemoveReactionFunction -Content-Type: application/json -Authorization: Bearer {{Token}} - -{ - "type": 3, - "ruleGuid": "{{RuleGuid}}", - "userId": "{{UserId}}" -} - -### -# Reactions - GetReactionsFunction -GET {{BaseApiUrl}}/GetReactionsFunction?rule_guid={{RuleGuid}}&user_id={{UserId}} - -### -# Reactions - GetAllReactionsFunction -GET {{BaseApiUrl}}/GetAllReactionsFunction?user_id={{UserId}} - ### # CMSAuth - AuthenticateCms GET {{BaseApiUrl}}/auth?scope=public_repo @@ -112,24 +80,3 @@ Authorization: Bearer {{Token}} "OrganisationId": "{{OrganisationId}}", "UserId": "{{UserId}}" } - -### -# User - RemoveUserCommentsAccountFunction -POST {{BaseApiUrl}}/RemoveUserCommentsAccountFunction -Content-Type: application/json -Authorization: Bearer {{Token}} - -{ - "UserId": "{{UserId}}" -} - -### -# User - ConnectUserToCommentsFunction -POST {{BaseApiUrl}}/ConnectUserToCommentsFunction -Content-Type: application/json -Authorization: Bearer {{Token}} - -{ - "UserId": "{{UserId}}", - "CommentsUserId": "{{CommentsUserId}}" -} \ No newline at end of file