Add GET bans

This commit is contained in:
Marco Realacci 2022-11-22 16:43:46 +01:00
parent 77e9f405c6
commit 4f391f0b65
7 changed files with 117 additions and 10 deletions

View file

@ -18,6 +18,7 @@ func (rt *_router) Handler() http.Handler {
rt.router.DELETE("/users/:user_id/followers/:follower_uid", rt.wrap(rt.DeleteFollow)) rt.router.DELETE("/users/:user_id/followers/:follower_uid", rt.wrap(rt.DeleteFollow))
rt.router.GET("/users/:user_id/following", rt.wrap(rt.GetFollowersFollowing)) rt.router.GET("/users/:user_id/following", rt.wrap(rt.GetFollowersFollowing))
rt.router.GET("/users/:user_id/bans", rt.wrap(rt.GetUserBans))
rt.router.PUT("/users/:user_id/bans/:ban_uid", rt.wrap(rt.PutBan)) rt.router.PUT("/users/:user_id/bans/:ban_uid", rt.wrap(rt.PutBan))
rt.router.DELETE("/users/:user_id/bans/:ban_uid", rt.wrap(rt.DeleteBan)) rt.router.DELETE("/users/:user_id/bans/:ban_uid", rt.wrap(rt.DeleteBan))

View file

@ -1,6 +1,7 @@
package api package api
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
@ -10,6 +11,45 @@ import (
"github.com/notherealmarco/WASAPhoto/service/database" "github.com/notherealmarco/WASAPhoto/service/database"
) )
func (rt *_router) GetUserBans(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
// Get user id
uid := ps.ByName("user_id")
if !authorization.SendAuthorizationError(ctx.Auth.UserAuthorized, uid, rt.db, w, rt.baseLogger, http.StatusNotFound) {
// A user should not be able to see other users' bans
return
}
// Get limits, or use default values
start_index, limit, err := helpers.GetLimits(r.URL.Query())
if err != nil {
// Send error if the limits are specified but invalid
helpers.SendBadRequest(w, "Invalid start_index or limit value", rt.baseLogger)
return
}
// Get bans
// We don't need to check if the user exists, because the authorization middleware already did that
bans, err := rt.db.GetUserBans(uid, start_index, limit)
if err != nil {
helpers.SendInternalError(err, "Database error: GetUserBans", w, rt.baseLogger)
return
}
// Return ban list
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) // is it needed?
json.NewEncoder(w).Encode(bans)
if err != nil {
helpers.SendInternalError(err, "Error encoding json", w, rt.baseLogger)
return
}
}
func (rt *_router) PutBan(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) { func (rt *_router) PutBan(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
uid := ps.ByName("user_id") uid := ps.ByName("user_id")

View file

@ -44,3 +44,40 @@ func (rt *_router) GetUserProfile(w http.ResponseWriter, r *http.Request, ps htt
return return
} }
} }
func (rt *_router) GetUserPhotos(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
// Get user id
uid := ps.ByName("user_id")
if !authorization.SendErrorIfNotLoggedIn(ctx.Auth.Authorized, rt.db, w, rt.baseLogger) ||
!helpers.SendNotFoundIfBanned(rt.db, ctx.Auth.GetUserID(), uid, w, rt.baseLogger) {
return
}
// Get limits, or use default values
start_index, limit, err := helpers.GetLimits(r.URL.Query())
if err != nil {
helpers.SendBadRequest(w, "Invalid start_index or limit value", rt.baseLogger)
return
}
// Get user photos
photos, err := rt.db.GetUserPhotos(uid, start_index, limit)
if err != nil {
helpers.SendInternalError(err, "Database error: GetUserPhotos", w, rt.baseLogger)
return
}
// Return user photos
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(photos)
if err != nil {
helpers.SendInternalError(err, "Error encoding json", w, rt.baseLogger)
return
}
}

View file

@ -56,6 +56,7 @@ type AppDatabase interface {
BanUser(uid string, ban string) (QueryResult, error) BanUser(uid string, ban string) (QueryResult, error)
UnbanUser(uid string, unban string) (QueryResult, error) UnbanUser(uid string, unban string) (QueryResult, error)
IsBanned(uid string, banner string) (bool, error) IsBanned(uid string, banner string) (bool, error)
GetUserBans(uid string, start_index int, limit int) (*[]structures.UIDName, error)
PostPhoto(uid string) (DBTransaction, int64, error) PostPhoto(uid string) (DBTransaction, int64, error)
DeletePhoto(uid string, photo int64) (bool, error) DeletePhoto(uid string, photo int64) (bool, error)
@ -64,7 +65,8 @@ type AppDatabase interface {
LikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error) LikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error)
UnlikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error) UnlikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error)
GetUserProfile(uid string) (QueryResult, *structures.UserProfile, error) // should support limits GetUserProfile(uid string) (QueryResult, *structures.UserProfile, error)
GetUserPhotos(uid string, start_index int, limit int) (*[]structures.UserPhoto, error)
GetUserStream(uid string, start_index int, limit int) (*[]structures.Photo, error) GetUserStream(uid string, start_index int, limit int) (*[]structures.Photo, error)
GetComments(uid string, photo_id int64, requesting_uid string, start_index int, offset int) (QueryResult, *[]structures.Comment, error) GetComments(uid string, photo_id int64, requesting_uid string, start_index int, offset int) (QueryResult, *[]structures.Comment, error)

View file

@ -39,7 +39,8 @@ func (db *appdbimpl) GetUserProfile(uid string) (QueryResult, *structures.UserPr
return ERR_INTERNAL, nil, err return ERR_INTERNAL, nil, err
} }
photos, err := db.getUserPhotos(uid) var photos int64
err = db.c.QueryRow(`SELECT COUNT(*) FROM "photos" WHERE "photos"."user" = ?`, uid).Scan(&following)
if err != nil { if err != nil {
return ERR_INTERNAL, nil, err return ERR_INTERNAL, nil, err
@ -54,7 +55,7 @@ func (db *appdbimpl) GetUserProfile(uid string) (QueryResult, *structures.UserPr
}, nil }, nil
} }
func (db *appdbimpl) getUserPhotos(uid string) (*[]structures.UserPhoto, error) { func (db *appdbimpl) GetUserPhotos(uid string, start_index int, limit int) (*[]structures.UserPhoto, error) {
// Get photos // Get photos
rows, err := db.c.Query(`SELECT "p"."id", "p"."date", rows, err := db.c.Query(`SELECT "p"."id", "p"."date",
@ -65,9 +66,16 @@ func (db *appdbimpl) getUserPhotos(uid string) (*[]structures.UserPhoto, error)
( (
SELECT COUNT(*) AS "comments" FROM "comments" AS "c" SELECT COUNT(*) AS "comments" FROM "comments" AS "c"
WHERE "c"."photo" = "p"."id" WHERE "c"."photo" = "p"."id"
),
EXISTS (
SELECT * FROM "likes" AS "l"
WHERE "l"."photo_id" = "p"."id"
AND "l"."user" = ?
) )
FROM "photos" AS "p" FROM "photos" AS "p"
WHERE "p"."user" = ?`, uid) WHERE "p"."user" = ?
OFFSET ?
LIMIT ?`, uid, uid, start_index, limit)
if err != nil { if err != nil {
// Return the error // Return the error
return nil, err return nil, err
@ -78,7 +86,7 @@ func (db *appdbimpl) getUserPhotos(uid string) (*[]structures.UserPhoto, error)
for rows.Next() { for rows.Next() {
// If there is a next row, we create an instance of Photo and add it to the slice // If there is a next row, we create an instance of Photo and add it to the slice
var photo structures.UserPhoto var photo structures.UserPhoto
err = rows.Scan(&photo.ID, &photo.Date, &photo.Likes, &photo.Comments) err = rows.Scan(&photo.ID, &photo.Date, &photo.Likes, &photo.Comments, &photo.Liked)
if err != nil { if err != nil {
// Return the error // Return the error
return nil, err return nil, err

View file

@ -235,6 +235,23 @@ func (db *appdbimpl) IsBanned(uid string, banner string) (bool, error) {
return cnt > 0, nil return cnt > 0, nil
} }
func (db *appdbimpl) GetUserBans(uid string, start_index int, limit int) (*[]structures.UIDName, error) {
rows, err := db.c.Query(`SELECT "ban", "user"."name" FROM "bans", "users"
WHERE "bans"."ban" = "users"."uid"
AND "bans"."user" = ?
OFFSET ?
LIMIT ?`, uid, start_index, limit)
bans, err := db.uidNameQuery(rows, err)
if err != nil {
return nil, err
}
return bans, nil
}
// Search by name // Search by name
func (db *appdbimpl) SearchByName(name string, requesting_uid string, start_index int, limit int) (*[]structures.UIDName, error) { func (db *appdbimpl) SearchByName(name string, requesting_uid string, start_index int, limit int) (*[]structures.UIDName, error) {

View file

@ -27,6 +27,7 @@ type Photo struct { //todo: move to structures
Likes int64 `json:"likes"` Likes int64 `json:"likes"`
Comments int64 `json:"comments"` Comments int64 `json:"comments"`
Date string `json:"date"` Date string `json:"date"`
Liked bool `json:"liked"`
} }
type UserPhoto struct { type UserPhoto struct {
@ -34,6 +35,7 @@ type UserPhoto struct {
Likes int64 `json:"likes"` Likes int64 `json:"likes"`
Comments int64 `json:"comments"` Comments int64 `json:"comments"`
Date string `json:"date"` Date string `json:"date"`
Liked bool `json:"liked"`
} }
type UserProfile struct { type UserProfile struct {
@ -41,5 +43,5 @@ type UserProfile struct {
Name string `json:"name"` Name string `json:"name"`
Following int64 `json:"following"` Following int64 `json:"following"`
Followers int64 `json:"followers"` Followers int64 `json:"followers"`
Photos *[]UserPhoto `json:"photos"` //todo: check json names Photos int64 `json:"photos"` //todo: check json names
} }