aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanail Dimitrov <danaildimitrov321@gmail.com>2021-02-04 18:50:19 +0200
committerDanail Dimitrov <danaildimitrov321@gmail.com>2021-02-04 18:50:19 +0200
commit7d288f0a353c0bf075f5bcb4d9fd44aac121c912 (patch)
tree6f4e4ee8de64f015076b3e1005720300130c9b2b
parent5d6e3c5518fdbace4b049f9043fb140e150fdaa6 (diff)
parentebf48cc5ad48199f0af9b8535c395b28f32b73a6 (diff)
downloadDevHive-7d288f0a353c0bf075f5bcb4d9fd44aac121c912.tar
DevHive-7d288f0a353c0bf075f5bcb4d9fd44aac121c912.tar.gz
DevHive-7d288f0a353c0bf075f5bcb4d9fd44aac121c912.zip
Merge branch 'dev' of https://github.com/Team-Kaleidoscope/DevHive into dev
-rw-r--r--README.md53
-rw-r--r--screenshots/admin-panel.pngbin0 -> 50920 bytes
-rw-r--r--screenshots/another-user-logged-in.pngbin0 -> 115600 bytes
-rw-r--r--screenshots/comment-page.pngbin0 -> 21475 bytes
-rw-r--r--screenshots/creating-post.pngbin0 -> 30921 bytes
-rw-r--r--screenshots/edit.pngbin0 -> 32121 bytes
-rw-r--r--screenshots/feed.pngbin0 -> 36789 bytes
-rw-r--r--screenshots/login.pngbin0 -> 20462 bytes
-rw-r--r--screenshots/post-page-with-comments.pngbin0 -> 53849 bytes
-rw-r--r--screenshots/post-page.pngbin0 -> 37766 bytes
-rw-r--r--screenshots/register.pngbin0 -> 25905 bytes
-rw-r--r--screenshots/your-profile-page.pngbin0 -> 50603 bytes
-rw-r--r--screenshots/your-settings-page.pngbin0 -> 41581 bytes
-rw-r--r--src/DevHive.Angular/src/app/components/feed/feed.component.ts4
-rw-r--r--src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html4
-rw-r--r--src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts4
-rw-r--r--src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html3
-rw-r--r--src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts7
-rw-r--r--src/DevHive.Angular/src/app/components/profile/profile.component.ts2
-rw-r--r--src/DevHive.Data/Repositories/CommentRepository.cs3
-rw-r--r--src/DevHive.Data/Repositories/FeedRepository.cs18
-rw-r--r--src/DevHive.Data/Repositories/LanguageRepository.cs3
-rw-r--r--src/DevHive.Data/Repositories/PostRepository.cs3
-rw-r--r--src/DevHive.Data/Repositories/TechnologyRepository.cs3
-rw-r--r--src/DevHive.Services/Services/CommentService.cs15
-rw-r--r--src/DevHive.Services/Services/FeedService.cs8
-rw-r--r--src/DevHive.Services/Services/PostService.cs19
-rw-r--r--src/DevHive.Services/Services/UserService.cs37
28 files changed, 162 insertions, 24 deletions
diff --git a/README.md b/README.md
index 6fbd5d3..c02f1e4 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,22 @@
DevHive is the social network solution for programmers. In it you can make posts to share with your friends, comment and more.
-It's built with ASP.NET Core as a back-end and Angular as a front-end. For more technical information, you can refer to the [Wiki](https://github.com/Team-Kaleidoscope/DevHive/wiki).
+It's built with [`ASP.NET Core`](https://docs.microsoft.com/en-us/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-5.0) as a back-end and [`Angular`](https://angular.io/) as a front-end. For more technical information, you can refer to the [Wiki](https://github.com/Team-Kaleidoscope/DevHive/wiki).
+
+## Contents:
+- [Setting up locally](#setting-up-locally)
+ - [Prerequisites](#prerequisites)
+ - [Getting started with the database](#getting-started-with-the-database)
+ - [Starting up the API](#starting-up-the-api)
+ - [Starting up the Front-end](#starting-up-the-front-end)
+ - [Important notes](#important-notes)
+- [Screenshots](#screenshots)
## Setting up locally
-DevHive can be easily self-hosted on your computer or server. There currently aren't any demo instances, so the only way to see it for yourself it to set it up.
+There currently aren't any demo instances, so the only way to try it out for yourself it to set it up locally, on a computer or server. In this section are explained the steps to do so.
-This tutorial is geared towards Linux-based systems.
+The steps are oriented around Linux-based systems.
### Prerequisites
@@ -16,14 +25,14 @@ There are some things you need to setup before even downloading the app.
Back-end (API) tools:
- [`dotnet 5.0`](https://docs.microsoft.com/en-us/dotnet/core/install/linux) or later
-- [`Entity Framework Core tool 5.0.2`](https://docs.microsoft.com/en-us/ef/core/cli/dotnet) or later
+- [`Entity Framework Core tool 5.0.2`](https://docs.microsoft.com/en-us/ef/core/cli/dotnet) or greater
- if you've already installed `dotnet`, you can just run this command `dotnet tool install dotnet-ef -g`
-- [`postresql 13.1`](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-20-04) or later (older versions might work, but haven't been tested)
+- [`postresql 13.1`](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-20-04) or greater (older versions might work, but haven't been tested)
- Fedora users could also refer to [this](https://computingforgeeks.com/how-to-install-postgresql-12-on-fedora/) guide
- Arch users can refer to the [ArchWiki](https://wiki.archlinux.org/index.php/PostgreSQL)
Front-end tools:
-- [`Angular CLI 11.0`](https://www.tecmint.com/install-angular-cli-on-linux/) or later (older versions might work, but haven't been tested)
+- [`Angular CLI 11.0.6`](https://www.tecmint.com/install-angular-cli-on-linux/) or greater (older versions might work, but haven't been tested)
### Getting started with the database
@@ -38,24 +47,40 @@ After installing all of the tools and setting up the database, you should have a
1. Navigate to the `src/DevHive.Web` folder
2. Edit the `appsettings.json` file, under "ConnectionStrings", type in the values, you setup in `ConnectionString.json` in `DevHive.Data`
- - On the third row there is a "Secret", it's used for encryption of User password, you can change it **but it must be made up of 64 letters and number!**
+ - On the third row there is a "Secret" field, it's used for encryption of User passwords, you can change it **but it must be made up of 64 letters and number!**
- There are also some cloud values that you can change. Currently, the project uses [Cloudinary](https://cloudinary.com/) as a place for uploading files. If you wish, you can setup your own account there, otherwise file uploading won't work.
3. Run `dotnet run` in the `DevHive.Web` folder
- feel free to [run the command in background](https://linuxize.com/post/how-to-run-linux-commands-in-background/) or [create a systemd service](https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6)
-If everything went well, you can now access the API on `http://localhost:5000/api` with something like [Postman](https://www.postman.com/) or the FOSS [Insomnia Designer](https://github.com/Kong/insomnia). Refer to the [API Endpoints](https://github.com/Team-Kaleidoscope/DevHive/wiki/API-Endpoints) page in the Wiki.
+If everything went well, you can now access the API on `http://localhost:5000/api` with something like [Postman](https://www.postman.com/) or the FOSS alternative [Insomnia Designer](https://github.com/Kong/insomnia). On where to send requests, refer to the [API Endpoints](https://github.com/Team-Kaleidoscope/DevHive/wiki/API-Endpoints) page in the Wiki.
### Starting up the Front-end
1. Navigate to `src/DevHive.Angular`
-2. Run `npm install`
-3. Run `ng serve`
+2. Run `npm install` to install all front-end packages
+3. Run `ng serve` to start up the front-end
- as with the API, you can [run the command in background](https://linuxize.com/post/how-to-run-linux-commands-in-background/) or [create a systemd service](https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6)
-If nothing broke, you can now access the front-end from `http://localhost:4200`. Also, don't forget that the API needs to be running *at the same time*, otherwise you won't get beyond the login and register screens!
+If everything went smoothly, you will be able to access the front-end from `http://localhost:4200`. Also, don't forget that the API needs to be running *at the same time*, otherwise you won't get beyond the Login and Register pages!
+
+### Important notes
+
+You can change on what port the API is ran, by changing the `HTTP_PORT` constant in `src/DevHive.Web/Program.cs`. If you do so, you **must** also update the front-end, because by default it will try to send requests to `http://localhost:5000`.
+- Go to `src/DevHive.Angular/src/app` and edit the `app-constants.module.ts` file, on the second row you're gonna see the variable `BASE_API_URL`, change it accoring to your API modifications.
-## Important notes
+You can change on what port the front-end is ran, by issuing the serve command with the `--port` parameter: `ng serve --port 5001`. But, **don't run it with the `--ssl` parameter!** SSL isn't supported yet and you'll have issues trying to use it! If you really need ssl, using a [reverse proxy](https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/) might be a viable alternative.
-You can change on what port the API is ran, by changing the `HTTP_PORT` constant in `src/DevHive.Web/Program.cs`. If you do so, you **must** also update the front-end, because by default it will try to send requests to port 5000. Go to `src/DevHive.Angular/src/app` and edit the `app-constants.module.ts` file, on the second row you're gonna see the variable `BASE_API_URL`, change it accoring to your API modifications.
+## Screenshots
-You can change on what port the Front-end is ran, by issueing the serve command with the `--port` parameter: `ng serve --port 5001`. But, **don't run it with the `--ssl` parameter!** SSL isn't supported yet, so it will throw errors! As an alternative, if you need ssl, is using a [reverse proxy](https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/).
+![](./screenshots/register.png)
+![](./screenshots/login.png)
+![](./screenshots/feed.png)
+![](./screenshots/creating-post.png)
+![](./screenshots/your-profile-page.png)
+![](./screenshots/your-settings-page.png)
+![](./screenshots/edit.png)
+![](./screenshots/post-page.png)
+![](./screenshots/post-page-with-comments.png)
+![](./screenshots/comment-page.png)
+![](./screenshots/another-user-logged-in.png)
+![](./screenshots/admin-panel.png)
diff --git a/screenshots/admin-panel.png b/screenshots/admin-panel.png
new file mode 100644
index 0000000..d8f1b3f
--- /dev/null
+++ b/screenshots/admin-panel.png
Binary files differ
diff --git a/screenshots/another-user-logged-in.png b/screenshots/another-user-logged-in.png
new file mode 100644
index 0000000..67f34e1
--- /dev/null
+++ b/screenshots/another-user-logged-in.png
Binary files differ
diff --git a/screenshots/comment-page.png b/screenshots/comment-page.png
new file mode 100644
index 0000000..f517dc9
--- /dev/null
+++ b/screenshots/comment-page.png
Binary files differ
diff --git a/screenshots/creating-post.png b/screenshots/creating-post.png
new file mode 100644
index 0000000..58081f2
--- /dev/null
+++ b/screenshots/creating-post.png
Binary files differ
diff --git a/screenshots/edit.png b/screenshots/edit.png
new file mode 100644
index 0000000..e448af3
--- /dev/null
+++ b/screenshots/edit.png
Binary files differ
diff --git a/screenshots/feed.png b/screenshots/feed.png
new file mode 100644
index 0000000..a456e2a
--- /dev/null
+++ b/screenshots/feed.png
Binary files differ
diff --git a/screenshots/login.png b/screenshots/login.png
new file mode 100644
index 0000000..378a682
--- /dev/null
+++ b/screenshots/login.png
Binary files differ
diff --git a/screenshots/post-page-with-comments.png b/screenshots/post-page-with-comments.png
new file mode 100644
index 0000000..d464053
--- /dev/null
+++ b/screenshots/post-page-with-comments.png
Binary files differ
diff --git a/screenshots/post-page.png b/screenshots/post-page.png
new file mode 100644
index 0000000..96428ef
--- /dev/null
+++ b/screenshots/post-page.png
Binary files differ
diff --git a/screenshots/register.png b/screenshots/register.png
new file mode 100644
index 0000000..70448b1
--- /dev/null
+++ b/screenshots/register.png
Binary files differ
diff --git a/screenshots/your-profile-page.png b/screenshots/your-profile-page.png
new file mode 100644
index 0000000..3701ea3
--- /dev/null
+++ b/screenshots/your-profile-page.png
Binary files differ
diff --git a/screenshots/your-settings-page.png b/screenshots/your-settings-page.png
new file mode 100644
index 0000000..61e39e6
--- /dev/null
+++ b/screenshots/your-settings-page.png
Binary files differ
diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.ts b/src/DevHive.Angular/src/app/components/feed/feed.component.ts
index 8e9ffbc..b412b3c 100644
--- a/src/DevHive.Angular/src/app/components/feed/feed.component.ts
+++ b/src/DevHive.Angular/src/app/components/feed/feed.component.ts
@@ -101,10 +101,14 @@ export class FeedComponent implements OnInit {
createPost(): void {
const postMessage = this.createPostFormGroup.get('newPostMessage')?.value;
+ this.dataArrived = false;
this._postService.createPostWithSessionStorageRequest(postMessage, this.files).subscribe(
(result: object) => {
this.goToProfile();
+ },
+ (err: HttpErrorResponse) => {
+ this.dataArrived = true;
}
);
}
diff --git a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html
index a8ebce7..4d381d1 100644
--- a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html
+++ b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.html
@@ -10,8 +10,8 @@
</div>
<div class="show-full-attachment" *ngIf="showFull" (click)="toggleShowFull()">
- <img class="attachment-img" *ngIf="paramURL.includes('image')" src="{{paramURL}}">
- <a class="attachment-download submit-btn" *ngIf="!paramURL.includes('image')" href="{{paramURL}}">Download attachment</a>
+ <img class="attachment-img" *ngIf="isImage" src="{{paramURL}}">
+ <a class="attachment-download submit-btn" *ngIf="!isImage" href="{{paramURL}}">Download attachment</a>
<div class="close">
</div>
diff --git a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts
index 6c468b0..1d00def 100644
--- a/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts
+++ b/src/DevHive.Angular/src/app/components/post-attachment/post-attachment.component.ts
@@ -7,6 +7,7 @@ import { Component, Input, OnInit } from '@angular/core';
})
export class PostAttachmentComponent implements OnInit {
@Input() paramURL: string;
+ public isImage = false;
public showFull = false;
public fileName: string;
public fileType: string;
@@ -15,7 +16,8 @@ export class PostAttachmentComponent implements OnInit {
{ }
ngOnInit(): void {
- this.fileType = this.paramURL.includes('image') ? 'img' : 'raw';
+ this.isImage = this.paramURL.includes('image') && !this.paramURL.endsWith('pdf');
+ this.fileType = this.isImage ? 'img' : 'raw';
this.fileName = this.paramURL.match('(?<=\/)(?:.(?!\/))+$')?.pop() ?? 'Attachment';
}
diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html
index d87c35c..502697d 100644
--- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html
+++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html
@@ -3,6 +3,7 @@
<div id="content" *ngIf="dataArrived">
<nav id="navigation">
<button class="submit-btn" (click)="goToProfile()">ᐊ Back</button>
+ <button class="submit-btn" (click)="navigateToAdminPanel()" *ngIf="isAdminUser">Panel</button>
<button class="submit-btn" (click)="logout()">Logout</button>
</nav>
<hr>
@@ -11,7 +12,7 @@
<img id="profile-picture" class="round-image" [src]="user.profilePictureURL">
<div id="submit-file">
<div id="upload-file" class="submit-btn">
- <input type="file" formControlName="fileUpload" (change)="onFileUpload($event)">
+ <input type="file" accept="image/*" formControlName="fileUpload" (change)="onFileUpload($event)">
</div>
<button class="submit-btn" type="submit">Update profile picture</button>
</div>
diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts
index 463b980..a484665 100644
--- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts
+++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts
@@ -13,6 +13,7 @@ import { Language } from 'src/models/language';
import { Technology } from 'src/models/technology';
import { TokenService } from 'src/app/services/token.service';
import { Title } from '@angular/platform-browser';
+import { AppConstants } from 'src/app/app-constants.module';
@Component({
selector: 'app-profile-settings',
@@ -24,6 +25,7 @@ export class ProfileSettingsComponent implements OnInit {
@ViewChild(ErrorBarComponent) private _errorBar: ErrorBarComponent;
@ViewChild(SuccessBarComponent) private _successBar: SuccessBarComponent;
private _urlUsername: string;
+ public isAdminUser = false;
public dataArrived = false;
public deleteAccountConfirm = false;
public showLanguages = false;
@@ -51,6 +53,7 @@ export class ProfileSettingsComponent implements OnInit {
this._userService.getUserByUsernameRequest(this._urlUsername).subscribe(
(res: object) => {
Object.assign(this.user, res);
+ this.isAdminUser = this.user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME);
this.finishUserLoading();
},
(err: HttpErrorResponse) => {
@@ -262,6 +265,10 @@ export class ProfileSettingsComponent implements OnInit {
this._router.navigate([this._router.url.substring(0, this._router.url.length - 9)]);
}
+ navigateToAdminPanel(): void {
+ this._router.navigate(['/admin-panel']);
+ }
+
logout(): void {
this._tokenService.logoutUserFromSessionStorage();
this.goToProfile();
diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.ts b/src/DevHive.Angular/src/app/components/profile/profile.component.ts
index f364c0d..a60250c 100644
--- a/src/DevHive.Angular/src/app/components/profile/profile.component.ts
+++ b/src/DevHive.Angular/src/app/components/profile/profile.component.ts
@@ -53,6 +53,7 @@ export class ProfileComponent implements OnInit {
this._userService.getUserByUsernameRequest(this._urlUsername).subscribe(
(res: object) => {
Object.assign(this.user, res);
+ this.isAdminUser = this.user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME);
this.loadLanguages();
},
(err: HttpErrorResponse) => {
@@ -117,7 +118,6 @@ export class ProfileComponent implements OnInit {
this.isTheLoggedInUser = true;
}
this.dataArrived = true;
- this.isAdminUser = this.user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME);
},
(err: HttpErrorResponse) => {
this.logout();
diff --git a/src/DevHive.Data/Repositories/CommentRepository.cs b/src/DevHive.Data/Repositories/CommentRepository.cs
index 382c666..bee7624 100644
--- a/src/DevHive.Data/Repositories/CommentRepository.cs
+++ b/src/DevHive.Data/Repositories/CommentRepository.cs
@@ -28,6 +28,9 @@ namespace DevHive.Data.Repositories
.FirstOrDefaultAsync(x => x.Id == id);
}
+ /// <summary>
+ /// This method returns the comment that is made at exactly the given time and by the given creator
+ /// </summary>
public async Task<Comment> GetCommentByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated)
{
return await this._context.Comments
diff --git a/src/DevHive.Data/Repositories/FeedRepository.cs b/src/DevHive.Data/Repositories/FeedRepository.cs
index 271c3a5..8d3e5e1 100644
--- a/src/DevHive.Data/Repositories/FeedRepository.cs
+++ b/src/DevHive.Data/Repositories/FeedRepository.cs
@@ -18,6 +18,15 @@ namespace DevHive.Data.Repositories
this._context = context;
}
+ /// <summary>
+ /// This returns a given amount of posts of all given friends, created before "firstRequestIssued",
+ /// ordered from latest to oldest (time created).
+ /// PageSize specifies how many posts to get, and pageNumber specifices how many posts to skip (pageNumber * pageSize).
+ ///
+ /// This method is used in the feed page.
+ /// Posts from friends are meant to be gotten in chunks, meaning you get X posts, and then get another amount of posts,
+ /// that are after the first X posts.
+ /// </summary>
public async Task<List<Post>> GetFriendsPosts(List<User> friendsList, DateTime firstRequestIssued, int pageNumber, int pageSize)
{
List<Guid> friendsIds = friendsList.Select(f => f.Id).ToList();
@@ -39,6 +48,15 @@ namespace DevHive.Data.Repositories
return posts;
}
+ /// <summary>
+ /// This returns a given amount of posts, that a user has made, created before "firstRequestIssued",
+ /// ordered from latest to oldest (time created).
+ /// PageSize specifies how many posts to get, and pageNumber specifices how many posts to skip (pageNumber * pageSize).
+ ///
+ /// This method is used in the profile page.
+ /// Posts from friends are meant to be gotten in chunks, meaning you get X posts, and then get another amount of posts,
+ /// that are after the first X posts.
+ /// </summary>
public async Task<List<Post>> GetUsersPosts(User user, DateTime firstRequestIssued, int pageNumber, int pageSize)
{
List<Post> posts = await this._context.Posts
diff --git a/src/DevHive.Data/Repositories/LanguageRepository.cs b/src/DevHive.Data/Repositories/LanguageRepository.cs
index 7f4b946..31d0b86 100644
--- a/src/DevHive.Data/Repositories/LanguageRepository.cs
+++ b/src/DevHive.Data/Repositories/LanguageRepository.cs
@@ -25,6 +25,9 @@ namespace DevHive.Data.Repositories
.FirstOrDefaultAsync(x => x.Name == languageName);
}
+ /// <summary>
+ /// Returns all technologies that exist in the database
+ /// </summary>
public HashSet<Language> GetLanguages()
{
return this._context.Languages.ToHashSet();
diff --git a/src/DevHive.Data/Repositories/PostRepository.cs b/src/DevHive.Data/Repositories/PostRepository.cs
index 0fec435..ed2fa1b 100644
--- a/src/DevHive.Data/Repositories/PostRepository.cs
+++ b/src/DevHive.Data/Repositories/PostRepository.cs
@@ -39,6 +39,9 @@ namespace DevHive.Data.Repositories
.FirstOrDefaultAsync(x => x.Id == id);
}
+ /// <summary>
+ /// This method returns the post that is made at exactly the given time and by the given creator
+ /// </summary>
public async Task<Post> GetPostByCreatorAndTimeCreatedAsync(Guid creatorId, DateTime timeCreated)
{
return await this._context.Posts
diff --git a/src/DevHive.Data/Repositories/TechnologyRepository.cs b/src/DevHive.Data/Repositories/TechnologyRepository.cs
index 7bb43cc..6f0d10f 100644
--- a/src/DevHive.Data/Repositories/TechnologyRepository.cs
+++ b/src/DevHive.Data/Repositories/TechnologyRepository.cs
@@ -25,6 +25,9 @@ namespace DevHive.Data.Repositories
.FirstOrDefaultAsync(x => x.Name == technologyName);
}
+ /// <summary>
+ /// Returns all technologies that exist in the database
+ /// </summary>
public HashSet<Technology> GetTechnologies()
{
return this._context.Technologies.ToHashSet();
diff --git a/src/DevHive.Services/Services/CommentService.cs b/src/DevHive.Services/Services/CommentService.cs
index e6b0eb0..3584e3a 100644
--- a/src/DevHive.Services/Services/CommentService.cs
+++ b/src/DevHive.Services/Services/CommentService.cs
@@ -103,6 +103,9 @@ namespace DevHive.Services.Services
#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);
@@ -110,6 +113,11 @@ namespace DevHive.Services.Services
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) ??
@@ -126,6 +134,9 @@ namespace DevHive.Services.Services
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));
@@ -139,7 +150,9 @@ namespace DevHive.Services.Services
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();
diff --git a/src/DevHive.Services/Services/FeedService.cs b/src/DevHive.Services/Services/FeedService.cs
index b9d1922..671df60 100644
--- a/src/DevHive.Services/Services/FeedService.cs
+++ b/src/DevHive.Services/Services/FeedService.cs
@@ -24,6 +24,10 @@ namespace DevHive.Services.Services
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;
@@ -53,6 +57,10 @@ namespace DevHive.Services.Services
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;
diff --git a/src/DevHive.Services/Services/PostService.cs b/src/DevHive.Services/Services/PostService.cs
index 3f98333..51f4d00 100644
--- a/src/DevHive.Services/Services/PostService.cs
+++ b/src/DevHive.Services/Services/PostService.cs
@@ -138,6 +138,9 @@ namespace DevHive.Services.Services
#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);
@@ -145,6 +148,11 @@ namespace DevHive.Services.Services
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) ??
@@ -161,6 +169,11 @@ namespace DevHive.Services.Services
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) ??
@@ -177,6 +190,9 @@ namespace DevHive.Services.Services
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));
@@ -190,6 +206,9 @@ namespace DevHive.Services.Services
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();
diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs
index b3a4987..9cc4a8e 100644
--- a/src/DevHive.Services/Services/UserService.cs
+++ b/src/DevHive.Services/Services/UserService.cs
@@ -47,6 +47,10 @@ namespace DevHive.Services.Services
}
#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))
@@ -60,6 +64,9 @@ namespace DevHive.Services.Services
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))
@@ -70,7 +77,7 @@ namespace DevHive.Services.Services
User user = this._userMapper.Map<User>(registerModel);
user.PasswordHash = PasswordModifications.GeneratePasswordHash(registerModel.Password);
- user.ProfilePicture = new ProfilePicture() { PictureURL = String.Empty };
+ user.ProfilePicture = new ProfilePicture() { PictureURL = "/assets/images/feed/profile-pic.png" };
// Make sure the default role exists
//TODO: Move when project starts
@@ -125,6 +132,9 @@ namespace DevHive.Services.Services
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);
@@ -162,6 +172,11 @@ namespace DevHive.Services.Services
#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..."
@@ -176,9 +191,6 @@ namespace DevHive.Services.Services
/* Check if user is trying to do something to himself, unless he's an admin */
/* Check roles */
- if (jwtRoleNames.Contains(Role.AdminRole))
- return true;
-
if (!jwtRoleNames.Contains(Role.AdminRole))
if (user.Id != id)
return false;
@@ -197,6 +209,9 @@ namespace DevHive.Services.Services
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();
@@ -208,6 +223,11 @@ namespace DevHive.Services.Services
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))
@@ -218,6 +238,10 @@ namespace DevHive.Services.Services
throw new ArgumentException("Username already exists!");
}
+ /// <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);
@@ -274,6 +298,11 @@ namespace DevHive.Services.Services
return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles));
}
+ /// <summary>
+ /// Returns the user with the Id in the model, adding to him the roles, languages and technologies, specified by the parameter model.
+ /// This practically maps HashSet<UpdateRoleServiceModel> to HashSet<Role> (and the equvalent HashSets for Languages and Technologies)
+ /// and assigns the latter to the returned user.
+ /// </summary>
private async Task<User> PopulateModel(UpdateUserServiceModel updateUserServiceModel)
{
User user = this._userMapper.Map<User>(updateUserServiceModel);