From ebb5c4e6f7fcc69372781a94c5a136c9a41ecd24 Mon Sep 17 00:00:00 2001
From: Marco Realacci <marco@marcorealacci.me>
Date: Tue, 22 Nov 2022 22:02:44 +0100
Subject: [PATCH] Fix query errors

---
 cmd/webapi/load-configuration.go   |   2 +-
 wasa.db => cmd/webapi/wasaphoto.db | Bin 61440 -> 53248 bytes
 service/api/helpers/get-limits.go  |   2 +-
 service/api/photos.go              |  33 +++++++++++++++++++++++------
 service/database/database.go       |   1 +
 service/database/db-comments.go    |  14 ++++++------
 service/database/db-likes.go       |   8 +++----
 service/database/db-photos.go      |  17 +++++++++++++++
 service/database/db-stream.go      |   4 ++--
 service/database/db-users.go       |  24 ++++++++++-----------
 10 files changed, 73 insertions(+), 32 deletions(-)
 rename wasa.db => cmd/webapi/wasaphoto.db (80%)

diff --git a/cmd/webapi/load-configuration.go b/cmd/webapi/load-configuration.go
index e9d17a7..cfd086f 100644
--- a/cmd/webapi/load-configuration.go
+++ b/cmd/webapi/load-configuration.go
@@ -26,7 +26,7 @@ type WebAPIConfiguration struct {
 	}
 	Debug bool
 	DB    struct {
-		Filename string `conf:"default:/tmp/decaf.db"`
+		Filename string `conf:"default:./wasaphoto.db"`
 	}
 	Data struct {
 		Path string `conf:"default:/tmp/wasaphoto"`
diff --git a/wasa.db b/cmd/webapi/wasaphoto.db
similarity index 80%
rename from wasa.db
rename to cmd/webapi/wasaphoto.db
index aa3c0d2a2d7f0d2607d13f585c83c47cb220d9e7..99da9f31e0f9a2b30959bb17adac2447d04b8b04 100644
GIT binary patch
literal 53248
zcmeI*PfXiZ90zbarb!%NuhoP+#E{%b6GX&Q;{1ha>N4sgR0uT0+Bj5^lb8`LiCYr3
zX_u)K^|t$Vsx(dNu?Nn(@4{uL-FxURlcs6XcHDc<3B^E)yP+K5YbpNo{POdApJ&H7
zehwS=RvKMf-EwwXR##04*9B1&K2lXd5N^=dIDPepAe|ZMFVLxYY<|$}4dMODyW`{^
zVJv(okelR?{4oCWTYrvyKmK&|`RM(~+u=j`w?S`4Is_m90SG_<0uVS?VDFvLkfJE!
zKIvN3rrm6OZg==-Y_Vh%%7$7le7s_)QJxl6XCtyKM|V5+PE;-%pO)3)8hx27D{;Q!
z!M4+NDvf$nUM`l6C8OkBe`l>^EH4$+yT<0M8ziQdj5|ijC@vZsDo^S}=_(o_rmhuL
zbNx0e!(w4$v2feq+wjCV+MYKKPiBE$6KB1&yjm!29xF>c`YIf)O)NGRR6bNhq0z3}
zUv(Zf=^uR+Yq#t0<q8L>B>7}~Zz&Q|rl-Yyi!0WgR?BX8JN@aX*Rr4Nk8^+}tJ~Si
z(O&#BTc~bz?Xy;RSb6(;Nm<fS)9{Ay0Mf#!1+%=iT%=W9HHziffX1Tjdc4IwEyd8+
z<)AV*CvI}b9(u=qxNEm-_KC%aNA<+Y*|ycP<Mf@eN1ug5%H*W@IL2eTTXe^=CxYAj
zopW1dF#Lt!4%qL{;bwMwQZS@UOo)#gyrxyF-C?hgx0WpF+&a=s|9dYPP!Z3b#<t_#
zBRo6WfDj%FzO%-oJQ7ow2?do8CI%h0toD^88;AF1MncNel(_#M=h||bP3Ox_Z*t9x
z)=TZXxr+ln1bZv#;d%NK(o^}PC~q!sRvh-3dHmRVW67iP#G^-bh%r*_T2LuW4I*{(
zQq|r}@EehzQXbvsuDlq06!4n5<?EkP*im)bE6NVz6Dw4+xO~ra&j#K-fyUtFjY+Tj
z<mTJ0=zKB~3!I-d$+JrITpDKQQ+9zbkuL=D3;B^wFhBqT5P$##AOHafKmY;|fB*y_
zaA5**Nivm8)!wRQ@;R+upSQGhJ#TAPHc1!LRywQOc0DtnUA1;<PCP(!>y}-!)3&80
zs+qc$PS^5UHIdI~shqCo@+sZQrP4Ha!-<PDcQ&8Q&^TGGmawWcb}pw?lbNcP$XeNY
z)w1W)I?ruIXq_bTLLe{5-{kiTs~`eF00Izz00bZa0SG_<0uX=z1RyY60a;Q+{yl=!
zn`=0Mu%yWB+k)Qp{}X{cCr`+)!z~!L1_1~_00Izz00bZa0SG_<0uZ=b0<)4S`sofJ
zv5bCt0t99xQ})vdfIr}W{c35Wwh({-1Rwwb2tWV=5P$##AOL}@Ccygt(;xlA009U<
z00Izz00bZa0SG_<0uX?}B^F@!|3z{jkOQ)HiK~gKK>z{}fB*y_009U<00Izz00f33
zuxk40;P0nz|6Te6f2N<l{eFV6`~SV`|AXN`U@H)S00bZa0SG_<0uX=z1Rwx`%PUay
z^?bjdEB3(3i0SXyem~LJ{r>>@S|C5s5e5iA00Izz00bZa0SG_<0uX=z1TI*h5EwCq
zTfRC4By?R%CN*6zC-V!5^g=p4mq;!o5(V);hDa@>a&8Fs`v0Xs{vt0gxPk}=0SG_<
z0uX=z1Rwwb2tWV=5P-mN1x5qXv|MvqExX<AL_}#)e6a0wold}g{{NXko(;D^*ct>N
z009U<00Izz00bZa0SG_<0;dE%5rd{IWN!I+?0<3FR;zZiX{lTE691<9$J6h=)xBK^
zvJ08)tNZ`>{r^+mNPqwYAOHafKmY;|fB*y_009VGDgpfezf0Aes0;)k009U<00Izz
P00bZa0SG|gOo4v^?N0Z8

delta 762
zcmZuv&rcIU6yBlR-JPA?oz~JW?SfrbV_8#4z!+mB(n1zPD7e&`NIX=2)JP~)(wbh3
z0m{Xj%lilTaqvu<_#bdm<J}X9CoXzw;=zN{ZEJ!$$v1E2&6{t&_ugzD1h&rt?~E|!
zIF2$141EkSFMZ3#+(<E@%IBOSopRKspXm{9;bZBPyeF?!fjrU(xke-+op?yp<a0F6
zZnD8vV<+AS8r*rRiF!Pa8sXZ~a=G;KMWt4$c4i76NgNQ?kp)+<9<x@LY9$L7oF@fy
z{vpHTTrMrcs4@j2N%FGos!$|0(%>yg-Q7||eP{?ZZu`6|m5q(kX06(@>Qvsz796vX
zoy<9=)pJ|su)L3>u%IT4w2UoZh=ph73(f;4|L0YhAPK2`zP4(auq8+0JqFACTb@8n
zLAI3-+&#~`Bi!s4^sE8j@c@KqC?KUS!J&FRpx7b!LI>}c*Vaqb;;3)rU4@FeuA@fX
zPr-Nk6TT?k_jQyHKmuQeF=Z0o;Az-Z`{64lL0jWE*Yk1%JN2-rN292*;4>~SZC2YL
zaH8n#LPssO{eOig)GXsmOxg4&M>;*^c8!Rr8wT1_eY)qBa=B8kc8z#ZWY^o42}m1+
zq-MalHVu0WpR}v8T}OVhJ9BV@4o9t5thE2MdYvXCZhmGin_o0%oyB24%9i1ft~B|~
zujG*%YMPld>K&wlh=~j~!<iq{bA$WO_+vg}_R!?rz7XHyXp04WqmfuQA&dfXsq^`c
GGNIo@!p5Wk

diff --git a/service/api/helpers/get-limits.go b/service/api/helpers/get-limits.go
index 2674d59..4e76960 100644
--- a/service/api/helpers/get-limits.go
+++ b/service/api/helpers/get-limits.go
@@ -6,7 +6,7 @@ import (
 )
 
 const (
-	DEFAULT_LIMIT  = 10 // todo: move to config
+	DEFAULT_LIMIT  = 15 // don't know if should be moved to config
 	DEFAULT_OFFSET = 0
 )
 
diff --git a/service/api/photos.go b/service/api/photos.go
index c8a835b..3c51297 100644
--- a/service/api/photos.go
+++ b/service/api/photos.go
@@ -15,7 +15,7 @@ import (
 
 func (rt *_router) PostPhoto(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
 
-	defer r.Body.Close()
+	//defer r.Body.Close()
 
 	uid := ps.ByName("user_id")
 
@@ -70,14 +70,35 @@ func (rt *_router) PostPhoto(w http.ResponseWriter, r *http.Request, ps httprout
 
 func (rt *_router) GetPhoto(w http.ResponseWriter, r *http.Request, ps httprouter.Params, ctx reqcontext.RequestContext) {
 
-	uid := ps.ByName("user_id")
-	photo_id := ps.ByName("photo_id")
-
-	if !helpers.VerifyUserOrNotFound(rt.db, uid, w, rt.baseLogger) {
+	if !authorization.SendErrorIfNotLoggedIn(ctx.Auth.Authorized, rt.db, w, rt.baseLogger) {
+		// We want the user to be authenticated
 		return
 	}
 
-	path := rt.dataPath + "/photos/" + uid + "/" + photo_id + ".jpg"
+	uid := ps.ByName("user_id")
+
+	photo_id_str := ps.ByName("photo_id")
+	photo_id, err := strconv.ParseInt(photo_id_str, 10, 64)
+
+	if err != nil {
+		helpers.SendBadRequest(w, "Invalid photo id", rt.baseLogger)
+		return
+	}
+
+	// This is also checking if the requesting user is banned by the author of the photo
+	exists, err := rt.db.PhotoExists(uid, photo_id, ctx.Auth.GetUserID())
+
+	if err != nil {
+		helpers.SendInternalError(err, "Database error: PhotoExists", w, rt.baseLogger)
+		return
+	}
+
+	if !exists {
+		helpers.SendNotFound(w, "Resource not found", rt.baseLogger)
+		return
+	}
+
+	path := rt.dataPath + "/photos/" + uid + "/" + photo_id_str + ".jpg"
 
 	file, err := os.Open(path)
 
diff --git a/service/database/database.go b/service/database/database.go
index 28c027f..955c385 100644
--- a/service/database/database.go
+++ b/service/database/database.go
@@ -60,6 +60,7 @@ type AppDatabase interface {
 
 	PostPhoto(uid string) (DBTransaction, int64, error)
 	DeletePhoto(uid string, photo int64) (bool, error)
+	PhotoExists(uid string, photo int64, requesting_uid string) (bool, error)
 
 	GetPhotoLikes(uid string, photo int64, requesting_uid string, start_index int, offset int) (QueryResult, *[]structures.UIDName, error)
 	LikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error)
diff --git a/service/database/db-comments.go b/service/database/db-comments.go
index 4f2890c..20ef183 100644
--- a/service/database/db-comments.go
+++ b/service/database/db-comments.go
@@ -89,15 +89,17 @@ func (db *appdbimpl) GetComments(uid string, photo_id int64, requesting_uid stri
 		return ERR_NOT_FOUND, nil, err
 	}
 
-	rows, err := db.c.Query(`SELECT "c"."id", "c"."user", "c"."comment", "c"."date" FROM "comments" AS "c"
+	rows, err := db.c.Query(`SELECT "c"."id", "c"."user", "c"."comment", "c"."date", "u"."name"
+								FROM "comments" AS "c", "users" AS "u"
 								WHERE "c"."photo" = ?
 								AND "c"."user" NOT IN (
 									SELECT "bans"."user" FROM "bans"
-									WHERE "bans"."user" = ?
-									AND "bans"."ban" = "c"."user"
+									WHERE "bans"."user" = "c"."user"
+									AND "bans"."ban" = ?
 								)
-								OFFSET ?
-								LIMIT ?`, photo_id, requesting_uid, start_index, limit)
+								AND "u"."uid" = "c"."user"
+								LIMIT ?
+								OFFSET ?`, photo_id, requesting_uid, limit, start_index)
 
 	if err != nil {
 		return ERR_INTERNAL, nil, err
@@ -109,7 +111,7 @@ func (db *appdbimpl) GetComments(uid string, photo_id int64, requesting_uid stri
 
 	for rows.Next() {
 		var c structures.Comment
-		err = rows.Scan(&c.CommentID, &c.UID, &c.Comment, &c.Date)
+		err = rows.Scan(&c.CommentID, &c.UID, &c.Comment, &c.Date, &c.Name)
 		if err != nil {
 			return ERR_INTERNAL, nil, err
 		}
diff --git a/service/database/db-likes.go b/service/database/db-likes.go
index 164129e..3ff358f 100644
--- a/service/database/db-likes.go
+++ b/service/database/db-likes.go
@@ -22,12 +22,12 @@ func (db *appdbimpl) GetPhotoLikes(uid string, photo int64, requesting_uid strin
 								WHERE "likes"."photo_id" = ?
 								AND "likes"."user" NOT IN (
 									SELECT "bans"."user" FROM "bans"
-									WHERE "bans"."user" = ?
-									AND "bans"."ban" = "likes"."user"
+									WHERE "bans"."user" = "likes"."user"
+									AND "bans"."ban" = ?
 								)
 								AND "likes"."user" = "users"."uid"
-								OFFSET ?
-								LIMIT ?`, photo, requesting_uid, start_index, limit)
+								LIMIT ?
+								OFFSET ?`, photo, requesting_uid, limit, start_index)
 	if err != nil {
 		return ERR_INTERNAL, nil, err
 	}
diff --git a/service/database/db-photos.go b/service/database/db-photos.go
index 5ad16d0..95f857f 100644
--- a/service/database/db-photos.go
+++ b/service/database/db-photos.go
@@ -52,3 +52,20 @@ func (db *appdbimpl) photoExists(uid string, photo int64) (bool, error) {
 	}
 	return cnt > 0, nil
 }
+
+func (db *appdbimpl) PhotoExists(uid string, photo int64, requesting_uid string) (bool, error) {
+
+	var cnt int64
+	err := db.c.QueryRow(`SELECT COUNT(*) FROM "photos"
+							WHERE "id" = ?
+							AND "user" = ?
+							AND "user" NOT IN (
+								SELECT "bans"."user" FROM "bans"
+								WHERE "bans"."user" = "photos"."user"
+								AND "bans"."ban" = ?
+							)`, photo, uid, requesting_uid).Scan(&cnt)
+	if err != nil {
+		return false, err
+	}
+	return cnt > 0, nil
+}
diff --git a/service/database/db-stream.go b/service/database/db-stream.go
index 4d7ab8d..ce54c52 100644
--- a/service/database/db-stream.go
+++ b/service/database/db-stream.go
@@ -26,8 +26,8 @@ func (db *appdbimpl) GetUserStream(uid string, start_index int, limit int) (*[]s
 									SELECT "user" FROM "bans" WHERE "ban" = ?
 								)
 								ORDER BY "p"."date" DESC
-								OFFSET ?
-								LIMIT ?`, uid, uid, start_index, limit)
+								LIMIT ?
+								OFFSET ?`, uid, uid, limit, start_index)
 	if err != nil {
 		// Return the error
 		return nil, err
diff --git a/service/database/db-users.go b/service/database/db-users.go
index a87768b..c05b561 100644
--- a/service/database/db-users.go
+++ b/service/database/db-users.go
@@ -66,8 +66,8 @@ func (db *appdbimpl) GetUserFollowers(uid string, requesting_uid string, start_i
 							
 							AND "follows"."follower" NOT IN (
 								SELECT "bans"."user" FROM "bans"
-								WHERE "bans"."user" = ?
-								AND "bans"."ban" = "follows"."follower"
+								WHERE "bans"."user" = "follows"."follower"
+								AND "bans"."ban" = ?
 							)
 
 							AND "followed" = ?
@@ -102,13 +102,13 @@ func (db *appdbimpl) GetUserFollowing(uid string, requesting_uid string, start_i
 
 							AND "follows"."followed" NOT IN (
 								SELECT "bans"."user" FROM "bans"
-								WHERE "bans"."user" = ?
-								AND "bans"."ban" = "follows"."followed"
+								WHERE "bans"."user" = "follows"."followed"
+								AND "bans"."ban" = ?
 							)
 
 							AND "follower" = ?
-							OFFSET ?
-							LIMIT ?`, uid, requesting_uid, start_index, offset)
+							LIMIT ?
+							OFFSET ?`, uid, requesting_uid, offset, start_index)
 
 	following, err := db.uidNameQuery(rows, err)
 
@@ -237,11 +237,11 @@ func (db *appdbimpl) IsBanned(uid string, banner string) (bool, error) {
 
 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"
+	rows, err := db.c.Query(`SELECT "ban", "users"."name" FROM "bans", "users"
 							WHERE "bans"."ban" = "users"."uid"
 							AND "bans"."user" = ?
-							OFFSET ?
-							LIMIT ?`, uid, start_index, limit)
+							LIMIT ?
+							OFFSET ?`, uid, limit, start_index)
 
 	bans, err := db.uidNameQuery(rows, err)
 
@@ -256,15 +256,15 @@ func (db *appdbimpl) GetUserBans(uid string, start_index int, limit int) (*[]str
 func (db *appdbimpl) SearchByName(name string, requesting_uid string, start_index int, limit int) (*[]structures.UIDName, error) {
 
 	rows, err := db.c.Query(`SELECT "uid", "name" FROM "users"
-							WHERE "name" LIKE ?
+							WHERE "name" LIKE '%' || ? || '%'
 
 							AND "uid" NOT IN (
 								SELECT "bans"."user" FROM "bans"
 								WHERE "bans"."user" = "users"."uid"
 								AND "bans"."ban" = ?
 							)
-							OFFSET ?
-							LIMIT ?`, name, requesting_uid, start_index, limit)
+							LIMIT ?
+							OFFSET ?`, name, requesting_uid, limit, start_index)
 
 	users, err := db.uidNameQuery(rows, err)