33using exercise . wwwapi . DTOs ;
44using exercise . wwwapi . DTOs . GetUsers ;
55using exercise . wwwapi . DTOs . Posts ;
6+ using exercise . wwwapi . Helpers ;
67using exercise . wwwapi . Models ;
78using exercise . wwwapi . Repository ;
89using Microsoft . AspNetCore . Authorization ;
910using Microsoft . AspNetCore . Mvc ;
1011using Microsoft . EntityFrameworkCore ;
12+ using Microsoft . Extensions . Hosting ;
1113using System . Security . Claims ;
1214
1315namespace exercise . wwwapi . Endpoints
@@ -19,63 +21,70 @@ public static void ConfigurePostEndpoints(this WebApplication app)
1921 var posts = app . MapGroup ( "posts" ) ;
2022 posts . MapPost ( "/" , CreatePost ) . WithSummary ( "Create post" ) ;
2123 posts . MapGet ( "/" , GetAllPosts ) . WithSummary ( "Get all posts" ) ;
22- posts . MapPatch ( "/{id }" , UpdatePost ) . WithSummary ( "Update a certain post" ) ;
23- posts . MapDelete ( "/{id }" , DeletePost ) . WithSummary ( "Remove a certain post" ) ;
24+ posts . MapPatch ( "/{postid }" , UpdatePost ) . WithSummary ( "Update a certain post" ) ;
25+ posts . MapDelete ( "/{postid }" , DeletePost ) . WithSummary ( "Remove a certain post" ) ;
2426
2527 posts . MapPost ( "/{postId}/comments" , AddCommentToPost ) . WithSummary ( "Add a new comment to a post" ) ;
2628 posts . MapGet ( "/{postId}/comments" , GetCommentsForPost ) . WithSummary ( "Get comments for a specific post" ) ;
2729
2830 // Standalone comment endpoints for editing/deleting
2931 var comments = app . MapGroup ( "comments" ) ;
30- comments . MapPatch ( "/{id }" , UpdateComment ) . WithSummary ( "Edit an existing comment" ) ;
31- comments . MapDelete ( "/{id }" , DeleteCommentById ) . WithSummary ( "Remove an existing comment" ) ;
32+ comments . MapPatch ( "/{commentId }" , UpdateComment ) . WithSummary ( "Edit an existing comment" ) ;
33+ comments . MapDelete ( "/{commentId }" , DeleteCommentById ) . WithSummary ( "Remove an existing comment" ) ;
3234
3335 // Endpoints to get by user
3436 posts . MapGet ( "/user/{userId}" , GetPostsByUser ) . WithSummary ( "Get posts by a specific user" ) ;
3537 comments . MapGet ( "/user/{userId}" , GetCommentsByUser ) . WithSummary ( "Get comments by a specific user" ) ;
3638 }
3739
38-
40+ [ Authorize ]
3941 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
4042 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
4143 [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
42- public static IResult CreatePost ( IRepository < User > userservice , IRepository < Post > postservice , IMapper mapper , CreatePostDTO request )
44+ public static IResult CreatePost (
45+ IRepository < User > userservice ,
46+ IRepository < Post > postservice ,
47+ IMapper mapper ,
48+ ClaimsPrincipal user ,
49+ CreatePostDTO request
50+ )
4351 {
44-
45- User ? user = userservice . GetById ( request . Userid ) ;
52+ int ? userid = user . UserRealId ( ) ;
53+ User ? dbUser = userservice . GetById ( userid ) ;
4654 if ( user == null )
4755 return Results . NotFound ( new ResponseDTO < Object > { Message = "Invalid userID" } ) ;
4856
4957 if ( string . IsNullOrWhiteSpace ( request . Content ) )
5058 return Results . BadRequest ( new ResponseDTO < Object > { Message = "Content cannot be empty" } ) ;
5159
52- Post post = new Post ( ) { CreatedAt = DateTime . UtcNow , NumLikes = 0 , UserId = request . Userid , Content = request . Content } ;
60+ Post post = new Post ( ) { CreatedAt = DateTime . UtcNow , NumLikes = 0 , UserId = dbUser . Id , Content = request . Content } ;
5361
5462 // is a try catch needed here?
5563 postservice . Insert ( post ) ;
5664 postservice . Save ( ) ;
5765
5866
59- UserBasicDTO userBasicDTO = mapper . Map < UserBasicDTO > ( user ) ;
67+ UserBasicDTO userBasicDTO = mapper . Map < UserBasicDTO > ( dbUser ) ;
6068 PostDTO postDTO = mapper . Map < PostDTO > ( post ) ;
6169 postDTO . User = userBasicDTO ;
6270
6371 ResponseDTO < PostDTO > response = new ResponseDTO < PostDTO >
6472 {
65- Message = "success " ,
73+ Message = "Success " ,
6674 Data = postDTO
6775 } ;
6876
6977 return Results . Created ( $ "/posts/{ post . Id } ", response ) ;
7078 }
79+ [ Authorize ]
7180 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
7281 public static IResult GetAllPosts ( IRepository < Post > service , IMapper mapper )
7382 {
7483 IEnumerable < Post > results = service . GetWithIncludes ( q => q . Include ( p => p . User ) . Include ( p => p . Comments ) . ThenInclude ( c => c . User ) ) ;
7584 IEnumerable < PostDTO > postDTOs = mapper . Map < IEnumerable < PostDTO > > ( results ) ;
7685 ResponseDTO < IEnumerable < PostDTO > > response = new ResponseDTO < IEnumerable < PostDTO > > ( )
7786 {
78- Message = "success " ,
87+ Message = "Success " ,
7988 Data = postDTOs
8089 } ;
8190 return TypedResults . Ok ( response ) ;
@@ -84,28 +93,25 @@ public static IResult GetAllPosts(IRepository<Post> service, IMapper mapper)
8493 [ Authorize ]
8594 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
8695 [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
87- public static IResult UpdatePost ( IRepository < Post > service , IMapper mapper , ClaimsPrincipal user , int id , UpdatePostDTO request )
96+ [ ProducesResponseType ( StatusCodes . Status403Forbidden ) ]
97+
98+ public static IResult UpdatePost ( IRepository < Post > service , IMapper mapper , ClaimsPrincipal user , int postid , UpdatePostDTO request )
8899 {
89100 if ( string . IsNullOrWhiteSpace ( request . Content ) ) return TypedResults . BadRequest ( new ResponseDTO < object > {
90101 Message = "Content cannot be empty"
91102 } ) ;
92103
93- Post ? post = service . GetById ( id , q=> q . Include ( p => p . User ) ) ;
94-
95-
104+ Post ? post = service . GetById ( postid , q=> q . Include ( p => p . User ) ) ;
96105
97106 if ( post == null ) return TypedResults . NotFound ( new ResponseDTO < Object > { Message = "Post not found" } ) ;
98107
99- var currentUserId = user . FindFirstValue ( ClaimTypes . NameIdentifier ) ;
100- if ( post . UserId . ToString ( ) != currentUserId )
108+ Console . WriteLine ( $ "Role: { user . Role ( ) } { Roles . student } | { post . UserId } { user . UserRealId ( ) } " ) ;
109+ if ( post . UserId != user . UserRealId ( ) && user . Role ( ) == ( int ) Roles . student )
101110 {
102- // Create your custom response object
103111 var forbiddenResponse = new ResponseDTO < object >
104112 {
105113 Message = "You are not authorized to edit this post."
106114 } ;
107-
108- // Return it as JSON with a 403 Forbidden status code
109115 return TypedResults . Json ( forbiddenResponse , statusCode : StatusCodes . Status403Forbidden ) ;
110116 }
111117
@@ -122,23 +128,41 @@ public static IResult UpdatePost(IRepository<Post> service, IMapper mapper, Clai
122128 return TypedResults . Ok ( new ResponseDTO < PostDTO > { Message = "Success" , Data = postDTO } ) ;
123129 }
124130
131+ [ Authorize ]
125132 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
126133 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
127- private static IResult DeletePost ( IRepository < Post > service , int id )
134+ [ ProducesResponseType ( StatusCodes . Status403Forbidden ) ]
135+ private static IResult DeletePost ( IRepository < Post > service , ClaimsPrincipal user , int postid )
128136 {
129- Post ? post = service . GetById ( id , q => q . Include ( p => p . User ) . Include ( p => p . Comments ) . ThenInclude ( c => c . User ) ) ;
137+ Post ? post = service . GetById ( postid , q => q . Include ( p => p . User ) . Include ( p => p . Comments ) . ThenInclude ( c => c . User ) ) ;
130138 if ( post == null ) return TypedResults . NotFound ( new ResponseDTO < Object > { Message = "Post not found" } ) ;
131139
132- service . Delete ( id ) ;
140+ if ( user . Role ( ) == ( int ) Roles . student && post . UserId != user . UserRealId ( ) )
141+ {
142+ var forbiddenResponse = new ResponseDTO < object >
143+ {
144+ Message = "You are not authorized to delete this post."
145+ } ;
146+ return TypedResults . Json ( forbiddenResponse , statusCode : StatusCodes . Status403Forbidden ) ;
147+ }
148+ service . Delete ( postid ) ;
133149 service . Save ( ) ;
134150
135151 return TypedResults . Ok ( new ResponseDTO < PostDTO > { Message = "Success" } ) ;
136152 }
137153
154+ [ Authorize ]
138155 [ ProducesResponseType ( StatusCodes . Status201Created ) ]
139156 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
140157 [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
141- private static IResult AddCommentToPost ( IRepository < PostComment > commentService , IRepository < Post > postService , IRepository < User > userService , IMapper mapper , int postId , CreatePostCommentDTO request )
158+ private static IResult AddCommentToPost (
159+ IRepository < PostComment > commentService ,
160+ IRepository < Post > postService ,
161+ IRepository < User > userService ,
162+ IMapper mapper ,
163+ ClaimsPrincipal user ,
164+ int postId ,
165+ CreatePostCommentDTO request )
142166 {
143167 // Check if post exists
144168 var post = postService . GetById ( postId ) ;
@@ -148,8 +172,8 @@ private static IResult AddCommentToPost(IRepository<PostComment> commentService,
148172 }
149173
150174 // Check if user exists
151- var user = userService . GetById ( request . Userid ) ;
152- if ( user == null )
175+ var dbUser = userService . GetById ( user . UserRealId ( ) ) ;
176+ if ( dbUser == null )
153177 {
154178 return TypedResults . NotFound ( new ResponseDTO < object > { Message = "User not found." } ) ;
155179 }
@@ -163,7 +187,7 @@ private static IResult AddCommentToPost(IRepository<PostComment> commentService,
163187 var comment = new PostComment
164188 {
165189 Content = request . Content ,
166- UserId = request . Userid ,
190+ UserId = dbUser . Id ,
167191 PostId = postId ,
168192 CreatedAt = DateTime . UtcNow
169193 } ;
@@ -177,6 +201,7 @@ private static IResult AddCommentToPost(IRepository<PostComment> commentService,
177201 return TypedResults . Created ( $ "/comments/{ comment . Id } ", new ResponseDTO < PostCommentDTO > { Message = "Success" , Data = commentDto } ) ;
178202 }
179203
204+ [ Authorize ]
180205 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
181206 private static IResult GetCommentsForPost ( IRepository < Post > postservice , IMapper mapper , int postId )
182207 {
@@ -190,17 +215,29 @@ private static IResult GetCommentsForPost(IRepository<Post> postservice, IMapper
190215 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
191216 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
192217 [ ProducesResponseType ( StatusCodes . Status400BadRequest ) ]
193- private static IResult UpdateComment ( IRepository < PostComment > service , IMapper mapper , int id , CreatePostCommentDTO request )
218+ private static IResult UpdateComment (
219+ IRepository < PostComment > service ,
220+ IMapper mapper ,
221+ ClaimsPrincipal user ,
222+ int commentId ,
223+ CreatePostCommentDTO request )
194224 {
195225 if ( string . IsNullOrWhiteSpace ( request . Content ) )
196226 {
197227 return TypedResults . BadRequest ( new ResponseDTO < object > { Message = "Content cannot be empty." } ) ;
198228 }
199229
200- var comment = service . GetById ( id , q => q . Include ( c => c . User ) ) ;
201- if ( comment == null )
230+ var comment = service . GetById ( commentId , q => q . Include ( c => c . User ) ) ;
231+ if ( comment == null ) return TypedResults . NotFound ( new ResponseDTO < object > { Message = "Comment not found." } ) ;
232+
233+ //Console.WriteLine($"Role:{user.Role()} {Roles.student.ToString()}| {comment.UserId} {user.UserRealId()}");
234+ if ( comment . UserId != user . UserRealId ( ) && user . Role ( ) == ( int ) Roles . student )
202235 {
203- return TypedResults . NotFound ( new ResponseDTO < object > { Message = "Comment not found." } ) ;
236+ var forbiddenResponse = new ResponseDTO < object >
237+ {
238+ Message = "You are not authorized to edit this comment."
239+ } ;
240+ return TypedResults . Json ( forbiddenResponse , statusCode : StatusCodes . Status403Forbidden ) ;
204241 }
205242
206243 comment . Content = request . Content ;
@@ -213,22 +250,33 @@ private static IResult UpdateComment(IRepository<PostComment> service, IMapper m
213250 return TypedResults . Ok ( new ResponseDTO < PostComment > { Message = "Comment updated successfully." , Data = commentDto } ) ;
214251 }
215252
253+ [ Authorize ]
216254 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
217255 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
218- private static IResult DeleteCommentById ( IRepository < PostComment > service , int id )
256+ private static IResult DeleteCommentById ( IRepository < PostComment > service , ClaimsPrincipal user , int commentId )
219257 {
220- var comment = service . GetById ( id ) ;
258+ var comment = service . GetById ( commentId ) ;
221259 if ( comment == null )
222260 {
223261 return TypedResults . NotFound ( new ResponseDTO < object > { Message = "Comment not found." } ) ;
224262 }
225263
226- service . Delete ( id ) ;
264+ if ( user . Role ( ) == ( int ) Roles . student && comment . UserId != user . UserRealId ( ) )
265+ {
266+ var forbiddenResponse = new ResponseDTO < object >
267+ {
268+ Message = "You are not authorized to delete this comment."
269+ } ;
270+ return TypedResults . Json ( forbiddenResponse , statusCode : StatusCodes . Status403Forbidden ) ;
271+ }
272+
273+ service . Delete ( commentId ) ;
227274 service . Save ( ) ;
228275
229276 return TypedResults . Ok ( new ResponseDTO < object > { Message = "Comment deleted successfully." } ) ;
230277 }
231278
279+ [ Authorize ]
232280 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
233281 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
234282 private static IResult GetPostsByUser ( IRepository < Post > service , IMapper mapper , int userid )
@@ -245,6 +293,7 @@ private static IResult GetPostsByUser(IRepository<Post> service, IMapper mapper,
245293 return TypedResults . Ok ( response ) ;
246294 }
247295
296+ [ Authorize ]
248297 [ ProducesResponseType ( StatusCodes . Status200OK ) ]
249298 [ ProducesResponseType ( StatusCodes . Status404NotFound ) ]
250299 private static IResult GetCommentsByUser ( IRepository < PostComment > service , IMapper mapper , int userid )
0 commit comments