Skip to content
This repository was archived by the owner on Jul 20, 2023. It is now read-only.

Commit c31fd08

Browse files
committed
delete photos and comments
1 parent 841f974 commit c31fd08

File tree

9 files changed

+205
-1
lines changed

9 files changed

+205
-1
lines changed

comment-service/app/http/controllers/controller.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/bstaijen/mariadb-for-microservices/comment-service/database"
1515
"github.com/bstaijen/mariadb-for-microservices/shared/util"
1616
jwt "github.com/dgrijalva/jwt-go"
17+
"github.com/gorilla/mux"
1718
"github.com/urfave/negroni"
1819

1920
"strconv"
@@ -270,6 +271,69 @@ func GetLastTenHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFun
270271
})
271272
}
272273

274+
// DeleteCommentHandler : is the handler to remove a comment in the database
275+
func DeleteCommentHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFunc {
276+
return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
277+
278+
var queryToken = r.URL.Query().Get("token")
279+
280+
if len(queryToken) < 1 {
281+
queryToken = r.Header.Get("token")
282+
}
283+
284+
if len(queryToken) < 1 {
285+
w.WriteHeader(http.StatusBadRequest)
286+
w.Write([]byte(string("token is mandatory")))
287+
return
288+
}
289+
290+
tok, err := jwt.Parse(queryToken, func(t *jwt.Token) (interface{}, error) {
291+
return []byte(cnf.SecretKey), nil
292+
})
293+
294+
if err != nil {
295+
util.SendErrorMessage(w, "You are not authorized")
296+
return
297+
}
298+
299+
claims := tok.Claims.(jwt.MapClaims)
300+
var userID = claims["sub"].(float64) // gets the ID
301+
302+
// Get commentID
303+
vars := mux.Vars(r)
304+
strID := vars["id"]
305+
commentID, err := strconv.Atoi(strID)
306+
307+
if err != nil {
308+
util.SendErrorMessage(w, "id needs to be numeric")
309+
return
310+
}
311+
312+
if commentID < 1 {
313+
util.SendErrorMessage(w, "id needs to be greater than 0")
314+
return
315+
}
316+
317+
comment, err := db.GetCommentByID(connection, commentID)
318+
if err != nil {
319+
util.SendError(w, err)
320+
return
321+
}
322+
323+
if comment.UserID != int(userID) {
324+
util.SendErrorMessage(w, "you can only remove your own comment")
325+
return
326+
}
327+
328+
_, err = db.DeleteCommentByID(connection, commentID)
329+
if err != nil {
330+
util.SendError(w, err)
331+
return
332+
}
333+
util.SendOKMessage(w, "Comment removed")
334+
})
335+
}
336+
273337
func getUsernames(cnf config.Config, input []*sharedModels.GetUsernamesRequest) []*sharedModels.GetUsernamesResponse {
274338
type Req struct {
275339
Requests []*sharedModels.GetUsernamesRequest `json:"requests"`

comment-service/app/http/routes/routes.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ func setRESTRoutes(db *sql.DB, cnf config.Config, router *mux.Router) *mux.Route
3131
controllers.ListCommentsFromUser(db, cnf),
3232
)).Methods("GET")
3333

34+
comments.Handle("/{id}/delete", negroni.New(
35+
negroni.HandlerFunc(middleware.AccessControlHandler),
36+
controllers.DeleteCommentHandler(db, cnf),
37+
)).Methods("POST")
38+
3439
// Create a comment /comments
3540
comments.Methods("POST").Handler(negroni.New(
3641
negroni.HandlerFunc(middleware.AccessControlHandler),

comment-service/database/db.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,15 @@ func GetLastTenComments(db *sql.DB, items []*sharedModels.CommentRequest) ([]*sh
169169
return responses, nil
170170
}
171171

172+
// DeleteCommentByID delete a comment in the database based on ID.
173+
func DeleteCommentByID(db *sql.DB, commentID int) (int64, error) {
174+
res, err := db.Exec("DELETE FROM comments WHERE id = ?", commentID)
175+
if err != nil {
176+
return 0, err
177+
}
178+
return res.RowsAffected()
179+
}
180+
172181
// ErrCommentNotFound error if comment does not exist in database
173182
var ErrCommentNotFound = errors.New("Comment does not exist")
174183

photo-service/app/http/controllers/incoming_controller.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import (
66
"errors"
77
"fmt"
88
"net/http"
9+
"strconv"
910

1011
"github.com/bstaijen/mariadb-for-microservices/photo-service/app/models"
1112
"github.com/bstaijen/mariadb-for-microservices/photo-service/database"
13+
"github.com/gorilla/mux"
1214
"github.com/urfave/negroni"
1315

1416
"io/ioutil"
@@ -162,6 +164,69 @@ func HotHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFunc {
162164
})
163165
}
164166

167+
// DeletePhotoHandler : is the handler to remove a photo in the database
168+
func DeletePhotoHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFunc {
169+
return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
170+
171+
var queryToken = r.URL.Query().Get("token")
172+
173+
if len(queryToken) < 1 {
174+
queryToken = r.Header.Get("token")
175+
}
176+
177+
if len(queryToken) < 1 {
178+
w.WriteHeader(http.StatusBadRequest)
179+
w.Write([]byte(string("token is mandatory")))
180+
return
181+
}
182+
183+
tok, err := jwt.Parse(queryToken, func(t *jwt.Token) (interface{}, error) {
184+
return []byte(cnf.SecretKey), nil
185+
})
186+
187+
if err != nil {
188+
util.SendErrorMessage(w, "You are not authorized")
189+
return
190+
}
191+
192+
claims := tok.Claims.(jwt.MapClaims)
193+
var userID = claims["sub"].(float64) // gets the ID
194+
195+
// Get photoID
196+
vars := mux.Vars(r)
197+
strID := vars["id"]
198+
photoID, err := strconv.Atoi(strID)
199+
200+
if err != nil {
201+
util.SendErrorMessage(w, "id needs to be numeric")
202+
return
203+
}
204+
205+
if photoID < 1 {
206+
util.SendErrorMessage(w, "id needs to be greater than 0")
207+
return
208+
}
209+
210+
photo, err := db.GetPhotoById(connection, photoID)
211+
if err != nil {
212+
util.SendError(w, err)
213+
return
214+
}
215+
216+
if photo.UserID != int(userID) {
217+
util.SendErrorMessage(w, "you can only remove your own photo")
218+
return
219+
}
220+
221+
_, err = db.DeletePhotoByID(connection, photoID)
222+
if err != nil {
223+
util.SendError(w, err)
224+
return
225+
}
226+
util.SendOKMessage(w, "Photo removed")
227+
})
228+
}
229+
165230
// FindResources searches for related resources to a collection of photos and adds them to the photo object.
166231
// By specifying parameters the caller of this func can determine which resources will be added and which
167232
// will be skippd. If userID is 0 or less then this func cannot determine if the user has voted on the photos.

photo-service/app/http/routes/routes.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ func setPhotoRoutes(db *sql.DB, cnf config.Config, router *mux.Router) *mux.Rout
3030
negroni.HandlerFunc(middleware.AcceptOPTIONS),
3131
))
3232

33+
image.Handle("/{id}/delete", negroni.New(
34+
negroni.HandlerFunc(middleware.AccessControlHandler),
35+
controllers.DeletePhotoHandler(db, cnf),
36+
)).Methods("POST")
37+
3338
// Add image for user /image/{id}
3439
image.Handle("/{id}", negroni.New(
3540
negroni.HandlerFunc(middleware.AccessControlHandler),

photo-service/database/db.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func InsertPhoto(db *sql.DB, photo *models.CreatePhoto) error {
5454

5555
// ListImagesByUserID returns a list of photo's uploaded by the user.
5656
func ListImagesByUserID(db *sql.DB, id int) ([]*models.Photo, error) {
57-
return selectQuery(db, "SELECT id, user_id, filename, title, createdAt, contentType, photo FROM photos WHERE user_id=?", id)
57+
return selectQuery(db, "SELECT id, user_id, filename, title, createdAt, contentType, photo FROM photos WHERE user_id=? ORDER BY createdAt DESC", id)
5858
}
5959

6060
// ListIncoming returns a list of photos ordered by last inserted
@@ -120,6 +120,15 @@ func GetPhotos(db *sql.DB, items []*sharedModels.PhotoRequest) ([]*sharedModels.
120120
return photos, nil
121121
}
122122

123+
// DeletePhotoByID delete a photo in the database based on ID.
124+
func DeletePhotoByID(db *sql.DB, photoID int) (int64, error) {
125+
res, err := db.Exec("DELETE FROM photos WHERE id = ?", photoID)
126+
if err != nil {
127+
return 0, err
128+
}
129+
return res.RowsAffected()
130+
}
131+
123132
// A parameter type prefixed with three dots (...) is called a variadic parameter.
124133
func selectQuery(db *sql.DB, query string, args ...interface{}) ([]*models.Photo, error) {
125134
rows, err := db.Query(query, args...)

webserver/webapp/controllers/UserController.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,40 @@ app.controller('UserController', function ($scope, $window, LocalStorage, ApiSer
115115
)
116116
}
117117

118+
$scope.deleteComment = function(commentID) {
119+
ApiService.deleteComment(commentID).then(
120+
function(response){
121+
console.info(response);
122+
123+
angular.forEach($scope.comment_tupel, function (tupel, index) {
124+
if (tupel.comment.id === commentID) {
125+
$scope.comment_tupel.splice(index, 1);
126+
}
127+
})
128+
129+
},
130+
function(error){
131+
console.error(error);
132+
}
133+
);
134+
};
135+
136+
$scope.deletePhoto = function(photoID) {
137+
ApiService.deletePhoto(photoID).then(
138+
function(response){
139+
console.info(response);
140+
141+
angular.forEach($scope.photos, function (photo, index) {
142+
if (photo.id === photoID) {
143+
$scope.photos.splice(index, 1);
144+
}
145+
})
146+
147+
},
148+
function(error){
149+
console.error(error);
150+
}
151+
);
152+
};
153+
118154
});

webserver/webapp/services/ApiService.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ app.factory('ApiService', function ($http, $q, LocalStorage, Upload) {
212212
getCommentsFromUser: function() {
213213
var url = composePhotoUrl('/comments/fromuser?token=' + LocalStorage.getToken());
214214
return get(url);
215+
},
216+
deleteComment: function(commentID) {
217+
var url = composeCommentUrl('/comments/' + commentID + '/delete?token=' + LocalStorage.getToken());
218+
return post(url, {})
219+
},
220+
deletePhoto: function(photoID) {
221+
var url = composePhotoUrl('/image/' + photoID + '/delete?token=' + LocalStorage.getToken());
222+
return post(url, {})
215223
}
216224
}
217225
});

webserver/webapp/view/UserView.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ <h2 class="text-center">{{username || ''}}</h2>
1919
<ul class="list-group">
2020
<li class="list-group-item">You added this photo {{displayMoment(photo.createdAt)}}.</li>
2121
</ul>
22+
<button type="button" class="btn btn-danger" ng-click="deletePhoto(photo.id)">Remove photo</button>
2223
</div>
2324
<div class="col-sm-4">
2425
<ul class="list-group">
@@ -45,6 +46,8 @@ <h2 class="text-center">{{username || ''}}</h2>
4546
</div>
4647
<div class="col-sm-4">
4748
You commented '<span class="text-muted">{{tupel.comment.comment}}</span>'.
49+
<br>
50+
<button type="button" class="btn btn-danger" ng-click="deleteComment(tupel.comment.id)">Remove comment</button>
4851
</div>
4952
<div class="col-sm-4">
5053
<ul class="list-group">

0 commit comments

Comments
 (0)