aboutsummaryrefslogtreecommitdiff
path: root/src/DevHive.Services/Services
diff options
context:
space:
mode:
authortranstrike <transtrike@gmail.com>2021-02-13 16:20:18 +0200
committertranstrike <transtrike@gmail.com>2021-02-13 16:20:18 +0200
commit98e17766b203734a1817eed94338e2d25f4395f7 (patch)
tree1266385a56cba56fd55c7faf661dd844bbdf5705 /src/DevHive.Services/Services
parent1ab34accfda22ee3ce5c7700e3b97ff3e932d649 (diff)
downloadDevHive-98e17766b203734a1817eed94338e2d25f4395f7.tar
DevHive-98e17766b203734a1817eed94338e2d25f4395f7.tar.gz
DevHive-98e17766b203734a1817eed94338e2d25f4395f7.zip
Project Restructure P.1
Diffstat (limited to 'src/DevHive.Services/Services')
-rw-r--r--src/DevHive.Services/Services/CloudinaryService.cs53
-rw-r--r--src/DevHive.Services/Services/CommentService.cs169
-rw-r--r--src/DevHive.Services/Services/FeedService.cs84
-rw-r--r--src/DevHive.Services/Services/LanguageService.cs89
-rw-r--r--src/DevHive.Services/Services/PostService.cs239
-rw-r--r--src/DevHive.Services/Services/RateService.cs80
-rw-r--r--src/DevHive.Services/Services/RoleService.cs70
-rw-r--r--src/DevHive.Services/Services/TechnologyService.cs90
-rw-r--r--src/DevHive.Services/Services/UserService.cs382
9 files changed, 0 insertions, 1256 deletions
diff --git a/src/DevHive.Services/Services/CloudinaryService.cs b/src/DevHive.Services/Services/CloudinaryService.cs
deleted file mode 100644
index 57955a2..0000000
--- a/src/DevHive.Services/Services/CloudinaryService.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-using CloudinaryDotNet;
-using CloudinaryDotNet.Actions;
-using DevHive.Services.Interfaces;
-using Microsoft.AspNetCore.Http;
-
-namespace DevHive.Services.Services
-{
- public class CloudinaryService : ICloudService
- {
- private readonly Cloudinary _cloudinary;
-
- public CloudinaryService(string cloudName, string apiKey, string apiSecret)
- {
- this._cloudinary = new Cloudinary(new Account(cloudName, apiKey, apiSecret));
- }
-
- public async Task<List<string>> UploadFilesToCloud(List<IFormFile> formFiles)
- {
- List<string> fileUrls = new();
- foreach (var formFile in formFiles)
- {
- string formFileId = Guid.NewGuid().ToString();
-
- using (var ms = new MemoryStream())
- {
- formFile.CopyTo(ms);
- byte[] formBytes = ms.ToArray();
-
- RawUploadParams rawUploadParams = new()
- {
- File = new FileDescription(formFileId, new MemoryStream(formBytes)),
- PublicId = formFileId,
- UseFilename = true
- };
-
- RawUploadResult rawUploadResult = await this._cloudinary.UploadAsync(rawUploadParams);
- fileUrls.Add(rawUploadResult.Url.AbsoluteUri);
- }
- }
-
- return fileUrls;
- }
-
- public async Task<bool> RemoveFilesFromCloud(List<string> fileUrls)
- {
- return true;
- }
- }
-}
diff --git a/src/DevHive.Services/Services/CommentService.cs b/src/DevHive.Services/Services/CommentService.cs
deleted file mode 100644
index e2b54c4..0000000
--- a/src/DevHive.Services/Services/CommentService.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Models;
-using DevHive.Services.Models.Comment;
-using System.IdentityModel.Tokens.Jwt;
-using System.Security.Claims;
-using DevHive.Services.Interfaces;
-using DevHive.Data.Interfaces.Repositories;
-using System.Linq;
-
-namespace DevHive.Services.Services
-{
- public class CommentService : ICommentService
- {
- private readonly IUserRepository _userRepository;
- private readonly IPostRepository _postRepository;
- private readonly ICommentRepository _commentRepository;
- private readonly IMapper _postMapper;
-
- public CommentService(IUserRepository userRepository, IPostRepository postRepository, ICommentRepository commentRepository, IMapper postMapper)
- {
- this._userRepository = userRepository;
- this._postRepository = postRepository;
- this._commentRepository = commentRepository;
- this._postMapper = postMapper;
- }
-
- #region Create
- public async Task<Guid> AddComment(CreateCommentServiceModel createCommentServiceModel)
- {
- if (!await this._postRepository.DoesPostExist(createCommentServiceModel.PostId))
- throw new ArgumentException("Post does not exist!");
-
- Comment comment = this._postMapper.Map<Comment>(createCommentServiceModel);
- comment.TimeCreated = DateTime.Now;
-
- comment.Creator = await this._userRepository.GetByIdAsync(createCommentServiceModel.CreatorId);
- comment.Post = await this._postRepository.GetByIdAsync(createCommentServiceModel.PostId);
-
- bool success = await this._commentRepository.AddAsync(comment);
- if (success)
- {
- Comment newComment = await this._commentRepository
- .GetCommentByIssuerAndTimeCreatedAsync(comment.Creator.Id, comment.TimeCreated);
-
- return newComment.Id;
- }
- else
- return Guid.Empty;
- }
- #endregion
-
- #region Read
- public async Task<ReadCommentServiceModel> GetCommentById(Guid id)
- {
- Comment comment = await this._commentRepository.GetByIdAsync(id) ??
- throw new ArgumentException("The comment does not exist");
-
- User user = await this._userRepository.GetByIdAsync(comment.Creator.Id) ??
- throw new ArgumentException("The user does not exist");
-
- ReadCommentServiceModel readCommentServiceModel = this._postMapper.Map<ReadCommentServiceModel>(comment);
- readCommentServiceModel.IssuerFirstName = user.FirstName;
- readCommentServiceModel.IssuerLastName = user.LastName;
- readCommentServiceModel.IssuerUsername = user.UserName;
-
- return readCommentServiceModel;
- }
- #endregion
-
- #region Update
- public async Task<Guid> UpdateComment(UpdateCommentServiceModel updateCommentServiceModel)
- {
- if (!await this._commentRepository.DoesCommentExist(updateCommentServiceModel.CommentId))
- throw new ArgumentException("Comment does not exist!");
-
- Comment comment = this._postMapper.Map<Comment>(updateCommentServiceModel);
- comment.TimeCreated = DateTime.Now;
-
- comment.Creator = await this._userRepository.GetByIdAsync(updateCommentServiceModel.CreatorId);
- comment.Post = await this._postRepository.GetByIdAsync(updateCommentServiceModel.PostId);
-
- bool result = await this._commentRepository.EditAsync(updateCommentServiceModel.CommentId, comment);
-
- if (result)
- return (await this._commentRepository.GetByIdAsync(updateCommentServiceModel.CommentId)).Id;
- else
- return Guid.Empty;
- }
- #endregion
-
- #region Delete
- public async Task<bool> DeleteComment(Guid id)
- {
- if (!await this._commentRepository.DoesCommentExist(id))
- throw new ArgumentException("Comment does not exist!");
-
- Comment comment = await this._commentRepository.GetByIdAsync(id);
- return await this._commentRepository.DeleteAsync(comment);
- }
- #endregion
-
- #region Validations
- /// <summary>
- /// Checks whether the user Id in the token and the given user Id match
- /// </summary>
- public async Task<bool> ValidateJwtForCreating(Guid userId, string rawTokenData)
- {
- User user = await this.GetUserForValidation(rawTokenData);
-
- return user.Id == userId;
- }
-
- /// <summary>
- /// Checks whether the comment, gotten with the commentId,
- /// is made by the user in the token
- /// or if the user in the token is an admin
- /// </summary>
- public async Task<bool> ValidateJwtForComment(Guid commentId, string rawTokenData)
- {
- Comment comment = await this._commentRepository.GetByIdAsync(commentId) ??
- throw new ArgumentException("Comment does not exist!");
- User user = await this.GetUserForValidation(rawTokenData);
-
- //If user made the comment
- if (comment.Creator.Id == user.Id)
- return true;
- //If user is admin
- else if (user.Roles.Any(x => x.Name == Role.AdminRole))
- return true;
- else
- return false;
- }
-
- /// <summary>
- /// Returns the user, via their Id in the token
- /// </summary>
- private async Task<User> GetUserForValidation(string rawTokenData)
- {
- JwtSecurityToken jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7));
-
- Guid jwtUserId = Guid.Parse(this.GetClaimTypeValues("ID", jwt.Claims).First());
- //HashSet<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims);
-
- User user = await this._userRepository.GetByIdAsync(jwtUserId) ??
- throw new ArgumentException("User does not exist!");
-
- return user;
- }
-
- /// <summary>
- /// Returns all values from a given claim type
- /// </summary>
- private List<string> GetClaimTypeValues(string type, IEnumerable<Claim> claims)
- {
- List<string> toReturn = new();
-
- foreach (var claim in claims)
- if (claim.Type == type)
- toReturn.Add(claim.Value);
-
- return toReturn;
- }
- #endregion
- }
-}
-
diff --git a/src/DevHive.Services/Services/FeedService.cs b/src/DevHive.Services/Services/FeedService.cs
deleted file mode 100644
index f2f4a3a..0000000
--- a/src/DevHive.Services/Services/FeedService.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Interfaces.Repositories;
-using DevHive.Data.Models;
-using DevHive.Services.Interfaces;
-using DevHive.Services.Models;
-using DevHive.Services.Models.Post;
-
-namespace DevHive.Services.Services
-{
- public class FeedService : IFeedService
- {
- private readonly IMapper _mapper;
- private readonly IFeedRepository _feedRepository;
- private readonly IUserRepository _userRepository;
-
- public FeedService(IFeedRepository feedRepository, IUserRepository userRepository, IMapper mapper)
- {
- this._feedRepository = feedRepository;
- this._userRepository = userRepository;
- this._mapper = mapper;
- }
-
- /// <summary>
- /// This method is used in the feed page.
- /// See the FeedRepository "GetFriendsPosts" menthod for more information on how it works.
- /// </summary>
- public async Task<ReadPageServiceModel> GetPage(GetPageServiceModel model)
- {
- User user = null;
-
- if (model.UserId != Guid.Empty)
- user = await this._userRepository.GetByIdAsync(model.UserId);
- else if (!string.IsNullOrEmpty(model.Username))
- user = await this._userRepository.GetByUsernameAsync(model.Username);
- else
- throw new ArgumentException("Invalid given data!");
-
- if (user == null)
- throw new ArgumentException("User doesn't exist!");
-
- if (user.Friends.Count == 0)
- throw new ArgumentException("User has no friends to get feed from!");
-
- List<Post> posts = await this._feedRepository
- .GetFriendsPosts(user.Friends.ToList(), model.FirstRequestIssued, model.PageNumber, model.PageSize);
-
- ReadPageServiceModel readPageServiceModel = new();
- foreach (Post post in posts)
- readPageServiceModel.Posts.Add(this._mapper.Map<ReadPostServiceModel>(post));
-
- return readPageServiceModel;
- }
-
- /// <summary>
- /// This method is used in the profile pages.
- /// See the FeedRepository "GetUsersPosts" menthod for more information on how it works.
- /// </summary>
- public async Task<ReadPageServiceModel> GetUserPage(GetPageServiceModel model)
- {
- User user = null;
-
- if (!string.IsNullOrEmpty(model.Username))
- user = await this._userRepository.GetByUsernameAsync(model.Username);
- else
- throw new ArgumentException("Invalid given data!");
-
- if (user == null)
- throw new ArgumentException("User doesn't exist!");
-
- List<Post> posts = await this._feedRepository
- .GetUsersPosts(user, model.FirstRequestIssued, model.PageNumber, model.PageSize);
-
- ReadPageServiceModel readPageServiceModel = new();
- foreach (Post post in posts)
- readPageServiceModel.Posts.Add(this._mapper.Map<ReadPostServiceModel>(post));
-
- return readPageServiceModel;
- }
- }
-}
diff --git a/src/DevHive.Services/Services/LanguageService.cs b/src/DevHive.Services/Services/LanguageService.cs
deleted file mode 100644
index a6364d8..0000000
--- a/src/DevHive.Services/Services/LanguageService.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Interfaces.Repositories;
-using DevHive.Data.Models;
-using DevHive.Services.Interfaces;
-using DevHive.Services.Models.Language;
-
-namespace DevHive.Services.Services
-{
- public class LanguageService : ILanguageService
- {
- private readonly ILanguageRepository _languageRepository;
- private readonly IMapper _languageMapper;
-
- public LanguageService(ILanguageRepository languageRepository, IMapper mapper)
- {
- this._languageRepository = languageRepository;
- this._languageMapper = mapper;
- }
-
- #region Create
- public async Task<Guid> CreateLanguage(CreateLanguageServiceModel createLanguageServiceModel)
- {
- if (await this._languageRepository.DoesLanguageNameExistAsync(createLanguageServiceModel.Name))
- throw new ArgumentException("Language already exists!");
-
- Language language = this._languageMapper.Map<Language>(createLanguageServiceModel);
- bool success = await this._languageRepository.AddAsync(language);
-
- if (success)
- {
- Language newLanguage = await this._languageRepository.GetByNameAsync(createLanguageServiceModel.Name);
- return newLanguage.Id;
- }
- else
- return Guid.Empty;
- }
- #endregion
-
- #region Read
- public async Task<ReadLanguageServiceModel> GetLanguageById(Guid id)
- {
- Language language = await this._languageRepository.GetByIdAsync(id);
-
- if (language == null)
- throw new ArgumentException("The language does not exist");
-
- return this._languageMapper.Map<ReadLanguageServiceModel>(language);
- }
-
- public HashSet<ReadLanguageServiceModel> GetLanguages()
- {
- HashSet<Language> languages = this._languageRepository.GetLanguages();
-
- return this._languageMapper.Map<HashSet<ReadLanguageServiceModel>>(languages);
- }
- #endregion
-
- #region Update
- public async Task<bool> UpdateLanguage(UpdateLanguageServiceModel languageServiceModel)
- {
- bool langExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id);
- bool newLangNameExists = await this._languageRepository.DoesLanguageNameExistAsync(languageServiceModel.Name);
-
- if (!langExists)
- throw new ArgumentException("Language does not exist!");
-
- if (newLangNameExists)
- throw new ArgumentException("Language name already exists in our data base!");
-
- Language lang = this._languageMapper.Map<Language>(languageServiceModel);
- return await this._languageRepository.EditAsync(languageServiceModel.Id, lang);
- }
- #endregion
-
- #region Delete
- public async Task<bool> DeleteLanguage(Guid id)
- {
- if (!await this._languageRepository.DoesLanguageExistAsync(id))
- throw new ArgumentException("Language does not exist!");
-
- Language language = await this._languageRepository.GetByIdAsync(id);
- return await this._languageRepository.DeleteAsync(language);
- }
- #endregion
- }
-}
diff --git a/src/DevHive.Services/Services/PostService.cs b/src/DevHive.Services/Services/PostService.cs
deleted file mode 100644
index fe91f23..0000000
--- a/src/DevHive.Services/Services/PostService.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Models;
-using DevHive.Services.Models.Post;
-using System.IdentityModel.Tokens.Jwt;
-using System.Security.Claims;
-using DevHive.Services.Interfaces;
-using DevHive.Data.Interfaces.Repositories;
-using System.Linq;
-using DevHive.Data.RelationModels;
-
-namespace DevHive.Services.Services
-{
- public class PostService : IPostService
- {
- private readonly ICloudService _cloudService;
- private readonly IUserRepository _userRepository;
- private readonly IPostRepository _postRepository;
- private readonly ICommentRepository _commentRepository;
- private readonly IMapper _postMapper;
-
- public PostService(ICloudService cloudService, IUserRepository userRepository, IPostRepository postRepository, ICommentRepository commentRepository, IMapper postMapper)
- {
- this._cloudService = cloudService;
- this._userRepository = userRepository;
- this._postRepository = postRepository;
- this._commentRepository = commentRepository;
- this._postMapper = postMapper;
- }
-
- #region Create
- public async Task<Guid> CreatePost(CreatePostServiceModel createPostServiceModel)
- {
- if (!await this._userRepository.DoesUserExistAsync(createPostServiceModel.CreatorId))
- throw new ArgumentException("User does not exist!");
-
- Post post = this._postMapper.Map<Post>(createPostServiceModel);
-
- if (createPostServiceModel.Files.Count != 0)
- {
- List<string> fileUrls = await _cloudService.UploadFilesToCloud(createPostServiceModel.Files);
- post.Attachments = this.GetPostAttachmentsFromUrls(post, fileUrls);
- }
-
- post.Creator = await this._userRepository.GetByIdAsync(createPostServiceModel.CreatorId);
- post.TimeCreated = DateTime.Now;
-
- bool success = await this._postRepository.AddAsync(post);
- if (success)
- {
- Post newPost = await this._postRepository
- .GetPostByCreatorAndTimeCreatedAsync(post.Creator.Id, post.TimeCreated);
-
- await this._postRepository.AddNewPostToCreator(createPostServiceModel.CreatorId, newPost);
-
- return newPost.Id;
- }
- else
- return Guid.Empty;
- }
- #endregion
-
- #region Read
- public async Task<ReadPostServiceModel> GetPostById(Guid id)
- {
- Post post = await this._postRepository.GetByIdAsync(id) ??
- throw new ArgumentException("The post does not exist!");
-
- // This can't happen in repo, because of how time is usually compared
- post.Comments = post.Comments
- .OrderByDescending(x => x.TimeCreated.ToFileTimeUtc())
- .ToList();
-
- User user = await this._userRepository.GetByIdAsync(post.Creator.Id) ??
- throw new ArgumentException("The user does not exist!");
-
- ReadPostServiceModel readPostServiceModel = this._postMapper.Map<ReadPostServiceModel>(post);
- readPostServiceModel.CreatorFirstName = user.FirstName;
- readPostServiceModel.CreatorLastName = user.LastName;
- readPostServiceModel.CreatorUsername = user.UserName;
- readPostServiceModel.FileUrls = post.Attachments.Select(x => x.FileUrl).ToList();
-
- return readPostServiceModel;
- }
- #endregion
-
- #region Update
- public async Task<Guid> UpdatePost(UpdatePostServiceModel updatePostServiceModel)
- {
- if (!await this._postRepository.DoesPostExist(updatePostServiceModel.PostId))
- throw new ArgumentException("Post does not exist!");
-
- Post post = this._postMapper.Map<Post>(updatePostServiceModel);
-
- if (updatePostServiceModel.Files.Count != 0)
- {
- if (await this._postRepository.DoesPostHaveFiles(updatePostServiceModel.PostId))
- {
- List<string> fileUrlsToRemove = await this._postRepository.GetFileUrls(updatePostServiceModel.PostId);
- bool success = await _cloudService.RemoveFilesFromCloud(fileUrlsToRemove);
- if (!success)
- throw new InvalidCastException("Could not delete files from the post!");
- }
-
- List<string> fileUrls = await _cloudService.UploadFilesToCloud(updatePostServiceModel.Files) ??
- throw new ArgumentNullException("Unable to upload images to cloud");
- post.Attachments = this.GetPostAttachmentsFromUrls(post, fileUrls);
- }
-
- post.Creator = await this._userRepository.GetByIdAsync(updatePostServiceModel.CreatorId);
- post.Comments = await this._commentRepository.GetPostComments(updatePostServiceModel.PostId);
- post.TimeCreated = DateTime.Now;
-
- bool result = await this._postRepository.EditAsync(updatePostServiceModel.PostId, post);
-
- if (result)
- return (await this._postRepository.GetByIdAsync(updatePostServiceModel.PostId)).Id;
- else
- return Guid.Empty;
- }
- #endregion
-
- #region Delete
- public async Task<bool> DeletePost(Guid id)
- {
- if (!await this._postRepository.DoesPostExist(id))
- throw new ArgumentException("Post does not exist!");
-
- Post post = await this._postRepository.GetByIdAsync(id);
-
- if (await this._postRepository.DoesPostHaveFiles(id))
- {
- List<string> fileUrls = await this._postRepository.GetFileUrls(id);
- bool success = await _cloudService.RemoveFilesFromCloud(fileUrls);
- if (!success)
- throw new InvalidCastException("Could not delete files from the post. Please try again");
- }
-
- return await this._postRepository.DeleteAsync(post);
- }
- #endregion
-
- #region Validations
- /// <summary>
- /// Checks whether the user Id in the token and the given user Id match
- /// </summary>
- public async Task<bool> ValidateJwtForCreating(Guid userId, string rawTokenData)
- {
- User user = await this.GetUserForValidation(rawTokenData);
-
- return user.Id == userId;
- }
-
- /// <summary>
- /// Checks whether the post, gotten with the postId,
- /// is made by the user in the token
- /// or if the user in the token is an admin
- /// </summary>
- public async Task<bool> ValidateJwtForPost(Guid postId, string rawTokenData)
- {
- Post post = await this._postRepository.GetByIdAsync(postId) ??
- throw new ArgumentException("Post does not exist!");
- User user = await this.GetUserForValidation(rawTokenData);
-
- //If user made the post
- if (post.Creator.Id == user.Id)
- return true;
- //If user is admin
- else if (user.Roles.Any(x => x.Name == Role.AdminRole))
- return true;
- else
- return false;
- }
-
- /// <summary>
- /// Checks whether the comment, gotten with the commentId,
- /// is made by the user in the token
- /// or if the user in the token is an admin
- /// </summary>
- public async Task<bool> ValidateJwtForComment(Guid commentId, string rawTokenData)
- {
- Comment comment = await this._commentRepository.GetByIdAsync(commentId) ??
- throw new ArgumentException("Comment does not exist!");
- User user = await this.GetUserForValidation(rawTokenData);
-
- //If user made the comment
- if (comment.Creator.Id == user.Id)
- return true;
- //If user is admin
- else if (user.Roles.Any(x => x.Name == Role.AdminRole))
- return true;
- else
- return false;
- }
-
- /// <summary>
- /// Returns the user, via their Id in the token
- /// </summary>
- private async Task<User> GetUserForValidation(string rawTokenData)
- {
- JwtSecurityToken jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7));
-
- Guid jwtUserId = Guid.Parse(this.GetClaimTypeValues("ID", jwt.Claims).First());
- //HashSet<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims);
-
- User user = await this._userRepository.GetByIdAsync(jwtUserId) ??
- throw new ArgumentException("User does not exist!");
-
- return user;
- }
-
- /// <summary>
- /// Returns all values from a given claim type
- /// </summary>
- private List<string> GetClaimTypeValues(string type, IEnumerable<Claim> claims)
- {
- List<string> toReturn = new();
-
- foreach (var claim in claims)
- if (claim.Type == type)
- toReturn.Add(claim.Value);
-
- return toReturn;
- }
- #endregion
-
- #region Misc
- private List<PostAttachments> GetPostAttachmentsFromUrls(Post post, List<string> fileUrls)
- {
- List<PostAttachments> postAttachments = new List<PostAttachments>();
- foreach (string url in fileUrls)
- postAttachments.Add(new PostAttachments { Post = post, FileUrl = url });
- return postAttachments;
- }
- #endregion
- }
-}
diff --git a/src/DevHive.Services/Services/RateService.cs b/src/DevHive.Services/Services/RateService.cs
deleted file mode 100644
index 204c550..0000000
--- a/src/DevHive.Services/Services/RateService.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Interfaces.Repositories;
-using DevHive.Data.Models;
-using DevHive.Services.Interfaces;
-using DevHive.Services.Models.Post.Rating;
-
-namespace DevHive.Services.Services
-{
- public class RateService : IRateService
- {
- private readonly IPostRepository _postRepository;
- private readonly IUserRepository _userRepository;
- private readonly IRatingRepository _ratingRepository;
- private readonly IMapper _mapper;
-
- public RateService(IPostRepository postRepository, IRatingRepository ratingRepository, IUserRepository userRepository, IMapper mapper)
- {
- this._postRepository = postRepository;
- this._ratingRepository = ratingRepository;
- this._userRepository = userRepository;
- this._mapper = mapper;
- }
-
- public async Task<ReadPostRatingServiceModel> RatePost(RatePostServiceModel ratePostServiceModel)
- {
- throw new NotImplementedException();
- // if (!await this._postRepository.DoesPostExist(ratePostServiceModel.PostId))
- // throw new ArgumentException("Post does not exist!");
-
- // if (!await this._userRepository.DoesUserExistAsync(ratePostServiceModel.UserId))
- // throw new ArgumentException("User does not exist!");
-
- // Post post = await this._postRepository.GetByIdAsync(ratePostServiceModel.PostId);
- // User user = await this._userRepository.GetByIdAsync(ratePostServiceModel.UserId);
-
- // if (this.HasUserRatedThisPost(user, post))
- // throw new ArgumentException("You can't rate the same post more then one(duh, amigo)");
-
- // this.Rate(user, post, ratePostServiceModel.Liked);
-
- // bool success = await this._ratingRepository.EditAsync(post.Rating.Id, post.Rating);
- // if (!success)
- // throw new InvalidOperationException("Unable to rate the post!");
-
- // Rating newRating = await this._ratingRepository.GetByIdAsync(post.Rating.Id);
- // return this._mapper.Map<ReadPostRatingServiceModel>(newRating);
- }
-
- public async Task<ReadPostRatingServiceModel> RemoveUserRateFromPost(Guid userId, Guid postId)
- {
- throw new NotImplementedException();
- // Post post = await this._postRepository.GetByIdAsync(postId);
- // User user = await this._userRepository.GetByIdAsync(userId);
-
- // if (!this.HasUserRatedThisPost(user, post))
- // throw new ArgumentException("You haven't rated this post, lmao!");
- }
-
- public bool HasUserRatedThisPost(User user, Post post)
- {
- throw new NotImplementedException();
- // return post.Rating.UsersThatRated
- // .Any(x => x.Id == user.Id);
- }
-
- private void Rate(User user, Post post, bool liked)
- {
- throw new NotImplementedException();
- // if (liked)
- // post.Rating.Rate++;
- // else
- // post.Rating.Rate--;
-
- // post.Rating.UsersThatRated.Add(user);
- }
- }
-}
diff --git a/src/DevHive.Services/Services/RoleService.cs b/src/DevHive.Services/Services/RoleService.cs
deleted file mode 100644
index a8b8e17..0000000
--- a/src/DevHive.Services/Services/RoleService.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Interfaces.Repositories;
-using DevHive.Data.Models;
-using DevHive.Services.Interfaces;
-using DevHive.Services.Models.Identity.Role;
-using DevHive.Services.Models.Language;
-
-namespace DevHive.Services.Services
-{
- public class RoleService : IRoleService
- {
- private readonly IRoleRepository _roleRepository;
- private readonly IMapper _roleMapper;
-
- public RoleService(IRoleRepository roleRepository, IMapper mapper)
- {
- this._roleRepository = roleRepository;
- this._roleMapper = mapper;
- }
-
- public async Task<Guid> CreateRole(CreateRoleServiceModel roleServiceModel)
- {
- if (await this._roleRepository.DoesNameExist(roleServiceModel.Name))
- throw new ArgumentException("Role already exists!");
-
- Role role = this._roleMapper.Map<Role>(roleServiceModel);
- bool success = await this._roleRepository.AddAsync(role);
-
- if (success)
- {
- Role newRole = await this._roleRepository.GetByNameAsync(roleServiceModel.Name);
- return newRole.Id;
- }
- else
- return Guid.Empty;
-
- }
-
- public async Task<RoleServiceModel> GetRoleById(Guid id)
- {
- Role role = await this._roleRepository.GetByIdAsync(id)
- ?? throw new ArgumentException("Role does not exist!");
-
- return this._roleMapper.Map<RoleServiceModel>(role);
- }
-
- public async Task<bool> UpdateRole(UpdateRoleServiceModel updateRoleServiceModel)
- {
- if (!await this._roleRepository.DoesRoleExist(updateRoleServiceModel.Id))
- throw new ArgumentException("Role does not exist!");
-
- if (await this._roleRepository.DoesNameExist(updateRoleServiceModel.Name))
- throw new ArgumentException("Role name already exists!");
-
- Role role = this._roleMapper.Map<Role>(updateRoleServiceModel);
- return await this._roleRepository.EditAsync(updateRoleServiceModel.Id, role);
- }
-
- public async Task<bool> DeleteRole(Guid id)
- {
- if (!await this._roleRepository.DoesRoleExist(id))
- throw new ArgumentException("Role does not exist!");
-
- Role role = await this._roleRepository.GetByIdAsync(id);
- return await this._roleRepository.DeleteAsync(role);
- }
- }
-}
diff --git a/src/DevHive.Services/Services/TechnologyService.cs b/src/DevHive.Services/Services/TechnologyService.cs
deleted file mode 100644
index 6dd6286..0000000
--- a/src/DevHive.Services/Services/TechnologyService.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using AutoMapper;
-using DevHive.Data.Interfaces.Repositories;
-using DevHive.Data.Models;
-using DevHive.Services.Interfaces;
-using DevHive.Services.Models.Technology;
-
-namespace DevHive.Services.Services
-{
- public class TechnologyService : ITechnologyService
- {
- private readonly ITechnologyRepository _technologyRepository;
- private readonly IMapper _technologyMapper;
-
- public TechnologyService(ITechnologyRepository technologyRepository, IMapper technologyMapper)
- {
- this._technologyRepository = technologyRepository;
- this._technologyMapper = technologyMapper;
- }
-
- #region Create
- public async Task<Guid> CreateTechnology(CreateTechnologyServiceModel technologyServiceModel)
- {
- if (await this._technologyRepository.DoesTechnologyNameExistAsync(technologyServiceModel.Name))
- throw new ArgumentException("Technology already exists!");
-
- Technology technology = this._technologyMapper.Map<Technology>(technologyServiceModel);
- bool success = await this._technologyRepository.AddAsync(technology);
-
- if (success)
- {
- Technology newTechnology = await this._technologyRepository.GetByNameAsync(technologyServiceModel.Name);
- return newTechnology.Id;
- }
- else
- return Guid.Empty;
- }
- #endregion
-
- #region Read
- public async Task<ReadTechnologyServiceModel> GetTechnologyById(Guid id)
- {
- Technology technology = await this._technologyRepository.GetByIdAsync(id);
-
- if (technology == null)
- throw new ArgumentException("The technology does not exist");
-
- return this._technologyMapper.Map<ReadTechnologyServiceModel>(technology);
- }
-
- public HashSet<ReadTechnologyServiceModel> GetTechnologies()
- {
- HashSet<Technology> technologies = this._technologyRepository.GetTechnologies();
-
- return this._technologyMapper.Map<HashSet<ReadTechnologyServiceModel>>(technologies);
- }
- #endregion
-
- #region Update
- public async Task<bool> UpdateTechnology(UpdateTechnologyServiceModel updateTechnologyServiceModel)
- {
- if (!await this._technologyRepository.DoesTechnologyExistAsync(updateTechnologyServiceModel.Id))
- throw new ArgumentException("Technology does not exist!");
-
- if (await this._technologyRepository.DoesTechnologyNameExistAsync(updateTechnologyServiceModel.Name))
- throw new ArgumentException("Technology name already exists!");
-
- Technology technology = this._technologyMapper.Map<Technology>(updateTechnologyServiceModel);
- bool result = await this._technologyRepository.EditAsync(updateTechnologyServiceModel.Id, technology);
-
- return result;
- }
- #endregion
-
- #region Delete
- public async Task<bool> DeleteTechnology(Guid id)
- {
- if (!await this._technologyRepository.DoesTechnologyExistAsync(id))
- throw new ArgumentException("Technology does not exist!");
-
- Technology technology = await this._technologyRepository.GetByIdAsync(id);
- bool result = await this._technologyRepository.DeleteAsync(technology);
-
- return result;
- }
- #endregion
- }
-}
diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs
deleted file mode 100644
index 22d5052..0000000
--- a/src/DevHive.Services/Services/UserService.cs
+++ /dev/null
@@ -1,382 +0,0 @@
-using AutoMapper;
-using DevHive.Services.Options;
-using DevHive.Services.Models.Identity.User;
-using System.Threading.Tasks;
-using DevHive.Data.Models;
-using System;
-using System.IdentityModel.Tokens.Jwt;
-using System.Security.Claims;
-using Microsoft.IdentityModel.Tokens;
-using System.Text;
-using System.Collections.Generic;
-using DevHive.Common.Models.Identity;
-using DevHive.Services.Interfaces;
-using DevHive.Data.Interfaces.Repositories;
-using System.Linq;
-using DevHive.Common.Models.Misc;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Identity;
-
-namespace DevHive.Services.Services
-{
- public class UserService : IUserService
- {
- private readonly IUserRepository _userRepository;
- private readonly IRoleRepository _roleRepository;
- private readonly ILanguageRepository _languageRepository;
- private readonly ITechnologyRepository _technologyRepository;
- private readonly UserManager<User> _userManager;
- private readonly RoleManager<Role> _roleManager;
- private readonly IMapper _userMapper;
- private readonly JWTOptions _jwtOptions;
- private readonly ICloudService _cloudService;
-
- public UserService(IUserRepository userRepository,
- ILanguageRepository languageRepository,
- IRoleRepository roleRepository,
- ITechnologyRepository technologyRepository,
- UserManager<User> userManager,
- RoleManager<Role> roleManager,
- IMapper mapper,
- JWTOptions jwtOptions,
- ICloudService cloudService)
- {
- this._userRepository = userRepository;
- this._roleRepository = roleRepository;
- this._userMapper = mapper;
- this._jwtOptions = jwtOptions;
- this._languageRepository = languageRepository;
- this._technologyRepository = technologyRepository;
- this._userManager = userManager;
- this._roleManager = roleManager;
- this._cloudService = cloudService;
- }
-
- #region Authentication
- /// <summary>
- /// Adds a new user to the database with the values from the given model.
- /// Returns a JSON Web Token (that can be used for authorization)
- /// </summary>
- public async Task<TokenModel> LoginUser(LoginServiceModel loginModel)
- {
- if (!await this._userRepository.DoesUsernameExistAsync(loginModel.UserName))
- throw new ArgumentException("Invalid username!");
-
- User user = await this._userRepository.GetByUsernameAsync(loginModel.UserName);
-
- if (user.PasswordHash != PasswordModifications.GeneratePasswordHash(loginModel.Password))
- throw new ArgumentException("Incorrect password!");
-
- return new TokenModel(WriteJWTSecurityToken(user.Id, user.UserName, user.Roles));
- }
-
- /// <summary>
- /// Returns a new JSON Web Token (that can be used for authorization) for the given user
- /// </summary>
- public async Task<TokenModel> RegisterUser(RegisterServiceModel registerModel)
- {
- if (await this._userRepository.DoesUsernameExistAsync(registerModel.UserName))
- throw new ArgumentException("Username already exists!");
-
- if (await this._userRepository.DoesEmailExistAsync(registerModel.Email))
- throw new ArgumentException("Email already exists!");
-
- User user = this._userMapper.Map<User>(registerModel);
- user.PasswordHash = PasswordModifications.GeneratePasswordHash(registerModel.Password);
- user.ProfilePicture = new ProfilePicture() { PictureURL = "/assets/images/feed/profile-pic.png" };
-
- // Make sure the default role exists
- //TODO: Move when project starts
- if (!await this._roleRepository.DoesNameExist(Role.DefaultRole))
- await this._roleRepository.AddAsync(new Role { Name = Role.DefaultRole });
-
- user.Roles.Add(await this._roleRepository.GetByNameAsync(Role.DefaultRole));
-
- IdentityResult userResult = await this._userManager.CreateAsync(user);
- User createdUser = await this._userRepository.GetByUsernameAsync(registerModel.UserName);
-
- if (!userResult.Succeeded)
- throw new ArgumentException("Unable to create a user");
-
- return new TokenModel(WriteJWTSecurityToken(createdUser.Id, createdUser.UserName, createdUser.Roles));
- }
- #endregion
-
- #region Read
- public async Task<UserServiceModel> GetUserById(Guid id)
- {
- User user = await this._userRepository.GetByIdAsync(id) ??
- throw new ArgumentException("User does not exist!");
-
- return this._userMapper.Map<UserServiceModel>(user);
- }
-
- public async Task<UserServiceModel> GetUserByUsername(string username)
- {
- User user = await this._userRepository.GetByUsernameAsync(username) ??
- throw new ArgumentException("User does not exist!");
-
- return this._userMapper.Map<UserServiceModel>(user);
- }
- #endregion
-
- #region Update
- public async Task<UserServiceModel> UpdateUser(UpdateUserServiceModel updateUserServiceModel)
- {
- await this.ValidateUserOnUpdate(updateUserServiceModel);
-
- User currentUser = await this._userRepository.GetByIdAsync(updateUserServiceModel.Id);
- await this.PopulateUserModel(currentUser, updateUserServiceModel);
-
- if (updateUserServiceModel.Friends.Count() > 0)
- await this.CreateRelationToFriends(currentUser, updateUserServiceModel.Friends.ToList());
- else
- currentUser.Friends.Clear();
-
- IdentityResult result = await this._userManager.UpdateAsync(currentUser);
-
- if (!result.Succeeded)
- throw new InvalidOperationException("Unable to edit user!");
-
- User newUser = await this._userRepository.GetByIdAsync(currentUser.Id);
- return this._userMapper.Map<UserServiceModel>(newUser);
- }
-
- /// <summary>
- /// Uploads the given picture and assigns it's link to the user in the database
- /// </summary>
- public async Task<ProfilePictureServiceModel> UpdateProfilePicture(UpdateProfilePictureServiceModel updateProfilePictureServiceModel)
- {
- User user = await this._userRepository.GetByIdAsync(updateProfilePictureServiceModel.UserId);
-
- if (!string.IsNullOrEmpty(user.ProfilePicture.PictureURL))
- {
- bool success = await _cloudService.RemoveFilesFromCloud(new List<string> { user.ProfilePicture.PictureURL });
- if (!success)
- throw new InvalidCastException("Could not delete old profile picture!");
- }
-
- string fileUrl = (await this._cloudService.UploadFilesToCloud(new List<IFormFile> { updateProfilePictureServiceModel.Picture }))[0] ??
- throw new ArgumentNullException("Unable to upload profile picture to cloud");
-
- bool successful = await this._userRepository.UpdateProfilePicture(updateProfilePictureServiceModel.UserId, fileUrl);
-
- if (!successful)
- throw new InvalidOperationException("Unable to change profile picture!");
-
- return new ProfilePictureServiceModel() { ProfilePictureURL = fileUrl };
- }
- #endregion
-
- #region Delete
- public async Task<bool> DeleteUser(Guid id)
- {
- if (!await this._userRepository.DoesUserExistAsync(id))
- throw new ArgumentException("User does not exist!");
-
- User user = await this._userRepository.GetByIdAsync(id);
- IdentityResult result = await this._userManager.DeleteAsync(user);
-
- return result.Succeeded;
- }
- #endregion
-
- #region Validations
- /// <summary>
- /// Checks whether the given user, gotten by the "id" property,
- /// is the same user as the one in the token (uness the user in the token has the admin role)
- /// and the roles in the token are the same as those in the user, gotten by the id in the token
- /// </summary>
- public async Task<bool> ValidJWT(Guid id, string rawTokenData)
- {
- // There is authorization name in the beginning, i.e. "Bearer eyJh..."
- var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7));
-
- Guid jwtUserID = new Guid(this.GetClaimTypeValues("ID", jwt.Claims).First());
- List<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims);
-
- User user = await this._userRepository.GetByIdAsync(jwtUserID)
- ?? throw new ArgumentException("User does not exist!");
-
- /* Check if user is trying to do something to himself, unless he's an admin */
-
- /* Check roles */
- if (!jwtRoleNames.Contains(Role.AdminRole))
- if (user.Id != id)
- return false;
-
- // Check if jwt contains all user roles (if it doesn't, jwt is either old or tampered with)
- foreach (var role in user.Roles)
- {
- if (!jwtRoleNames.Contains(role.Name))
- return false;
- }
-
- // Check if jwt contains only roles of user
- if (jwtRoleNames.Count != user.Roles.Count)
- return false;
-
- return true;
- }
-
- /// <summary>
- /// Returns all values from a given claim type
- /// </summary>
- private List<string> GetClaimTypeValues(string type, IEnumerable<Claim> claims)
- {
- List<string> toReturn = new();
-
- foreach (var claim in claims)
- if (claim.Type == type)
- toReturn.Add(claim.Value);
-
- return toReturn;
- }
-
- /// <summary>
- /// Checks whether the user in the model exists
- /// and whether the username in the model is already taken.
- /// If the check fails (is false), it throws an exception, otherwise nothing happens
- /// </summary>
- private async Task ValidateUserOnUpdate(UpdateUserServiceModel updateUserServiceModel)
- {
- if (!await this._userRepository.DoesUserExistAsync(updateUserServiceModel.Id))
- throw new ArgumentException("User does not exist!");
-
- if (updateUserServiceModel.Friends.Any(x => x.UserName == updateUserServiceModel.UserName))
- throw new ArgumentException("You cant add yourself as a friend(sry, bro)!");
-
- if (!this._userRepository.DoesUserHaveThisUsername(updateUserServiceModel.Id, updateUserServiceModel.UserName)
- && await this._userRepository.DoesUsernameExistAsync(updateUserServiceModel.UserName))
- throw new ArgumentException("Username already exists!");
-
- List<string> usernames = new();
- foreach (var friend in updateUserServiceModel.Friends)
- usernames.Add(friend.UserName);
-
- if (!await this._userRepository.ValidateFriendsCollectionAsync(usernames))
- throw new ArgumentException("One or more friends do not exist!");
- }
-
- /// <summary>
- /// Return a new JSON Web Token, containing the user id, username and roles.
- /// Tokens have an expiration time of 7 days.
- /// </summary>
- private string WriteJWTSecurityToken(Guid userId, string username, HashSet<Role> roles)
- {
- byte[] signingKey = Encoding.ASCII.GetBytes(_jwtOptions.Secret);
- HashSet<Claim> claims = new()
- {
- new Claim("ID", $"{userId}"),
- new Claim("Username", username)
- };
-
- foreach (var role in roles)
- {
- claims.Add(new Claim(ClaimTypes.Role, role.Name));
- }
-
- SecurityTokenDescriptor tokenDescriptor = new()
- {
- Subject = new ClaimsIdentity(claims),
- Expires = DateTime.Today.AddDays(7),
- SigningCredentials = new SigningCredentials(
- new SymmetricSecurityKey(signingKey),
- SecurityAlgorithms.HmacSha512Signature)
- };
-
- JwtSecurityTokenHandler tokenHandler = new();
- SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
- return tokenHandler.WriteToken(token);
- }
- #endregion
-
- #region Misc
- public async Task<TokenModel> SuperSecretPromotionToAdmin(Guid userId)
- {
- User user = await this._userRepository.GetByIdAsync(userId) ??
- throw new ArgumentException("User does not exist! Can't promote shit in this country...");
-
- if (!await this._roleRepository.DoesNameExist(Role.AdminRole))
- {
- Role adminRole = new()
- {
- Name = Role.AdminRole
- };
- adminRole.Users.Add(user);
-
- await this._roleRepository.AddAsync(adminRole);
- }
-
- Role admin = await this._roleManager.FindByNameAsync(Role.AdminRole);
-
- user.Roles.Add(admin);
- await this._userManager.UpdateAsync(user);
-
- User newUser = await this._userRepository.GetByIdAsync(userId);
-
- return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles));
- }
-
- private async Task PopulateUserModel(User user, UpdateUserServiceModel updateUserServiceModel)
- {
- user.UserName = updateUserServiceModel.UserName;
- user.FirstName = updateUserServiceModel.FirstName;
- user.LastName = updateUserServiceModel.LastName;
- user.Email = updateUserServiceModel.Email;
-
- //Do NOT allow a user to change his roles, unless he is an Admin
- bool isAdmin = await this._userManager.IsInRoleAsync(user, Role.AdminRole);
-
- if (isAdmin)
- {
- HashSet<Role> roles = new();
- foreach (var role in updateUserServiceModel.Roles)
- {
- Role returnedRole = await this._roleRepository.GetByNameAsync(role.Name) ??
- throw new ArgumentException($"Role {role.Name} does not exist!");
-
- roles.Add(returnedRole);
- }
- user.Roles = roles;
- }
-
- HashSet<Language> languages = new();
- int languagesCount = updateUserServiceModel.Languages.Count;
- for (int i = 0; i < languagesCount; i++)
- {
- Language language = await this._languageRepository.GetByNameAsync(updateUserServiceModel.Languages.ElementAt(i).Name) ??
- throw new ArgumentException("Invalid language name!");
-
- languages.Add(language);
- }
- user.Languages = languages;
-
- /* Fetch Technologies and replace model's*/
- HashSet<Technology> technologies = new();
- int technologiesCount = updateUserServiceModel.Technologies.Count;
- for (int i = 0; i < technologiesCount; i++)
- {
- Technology technology = await this._technologyRepository.GetByNameAsync(updateUserServiceModel.Technologies.ElementAt(i).Name) ??
- throw new ArgumentException("Invalid technology name!");
-
- technologies.Add(technology);
- }
- user.Technologies = technologies;
- }
-
- private async Task CreateRelationToFriends(User user, List<UpdateFriendServiceModel> friends)
- {
- foreach (var friend in friends)
- {
- User amigo = await this._userRepository.GetByUsernameAsync(friend.UserName);
-
- user.Friends.Add(amigo);
- amigo.Friends.Add(user);
-
- await this._userManager.UpdateAsync(amigo);
- }
- }
- #endregion
- }
-}