From eb3cdaa87f113597e47743e21cd03f1d18b248e4 Mon Sep 17 00:00:00 2001 From: array-in-a-matrix Date: Wed, 14 Aug 2024 23:42:42 -0400 Subject: [PATCH] use JSONY --- src/glimpse.nim | 2 +- src/helpers.nim | 3 +++ src/routes/auth.nim | 31 +++++++------------------------ src/routes/delete.nim | 33 +++++++++++++-------------------- src/routes/download.nim | 18 ++++++------------ src/routes/update.nim | 14 ++++---------- src/routes/upload.nim | 13 ++++--------- src/types/files.nim | 10 +++++++++- tests/test_1.sh | 6 +++--- 9 files changed, 50 insertions(+), 80 deletions(-) diff --git a/src/glimpse.nim b/src/glimpse.nim index e1fc8b0..e05ad31 100644 --- a/src/glimpse.nim +++ b/src/glimpse.nim @@ -1,4 +1,4 @@ -import std/[strutils, os, json, asyncdispatch, httpclient, with, logging] +import std/[strutils, os, json, asyncdispatch, httpclient, logging] import jester import checksums/sha3 diff --git a/src/helpers.nim b/src/helpers.nim index 64a0336..5a0dbaa 100644 --- a/src/helpers.nim +++ b/src/helpers.nim @@ -14,3 +14,6 @@ template respErr*(s: string): untyped = template respErr*(e: HttpCode, s: string): untyped = error s & reqInfo resp e, s + +template resp200*(json: string = ""): untyped = + resp Http200, json & "\n", "application/json" diff --git a/src/routes/auth.nim b/src/routes/auth.nim index a2dccc0..9ec711f 100644 --- a/src/routes/auth.nim +++ b/src/routes/auth.nim @@ -1,5 +1,6 @@ -import std/[strutils, with, logging] +import std/[strutils, logging] import jester +import jsony import norm/model import norm/postgres except error import checksums/sha3 @@ -13,7 +14,6 @@ proc createAuthenticationRoutes*() = username - string - required email - string - required password - string - required - returns: JSON ]# post "/api/v1/newUser": debug "Endpoint used.\n" & reqInfo @@ -38,18 +38,8 @@ proc createAuthenticationRoutes*() = var user = newUser(@"username", @"email", @"password") db.insert(user) - var userProfile: string - with userProfile: - add "[{" - add("\"username\": \"" & user.username & "\",") - add("\"email\": \"" & user.email & "\",") - add("\"password\": \"" & user.password & "\",") - add("\"token\": \"" & user.token & "\",") - add("\"fileCount\": \"" & $user.fileCount & "\"") - add "}]" - info "User created.\n" & reqInfo - resp Http200, userProfile & "\n", "application/json" + resp200 user.toJson() #[ request parameters: @@ -57,7 +47,6 @@ proc createAuthenticationRoutes*() = OR username - string - required via header password - string - required via header - returns: JSON ]# get "/api/v1/newSession": debug "Endpoint used.\n" & reqInfo @@ -66,7 +55,7 @@ proc createAuthenticationRoutes*() = if not H"Authorization".isEmptyOrWhitespace(): if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" db.generateToken(user) @@ -74,18 +63,12 @@ proc createAuthenticationRoutes*() = try: db.select(user, """"User".username = $1""", H"Username") except NotFoundError: - respErr"Incorrect username or password.\n" # fails if username is wrong but mentions password to obfuscates if a user exists or not + respErr "Incorrect username or password.\n" # fails if username is wrong but mentions password to obfuscates if a user exists or not if user.password == $Sha3_512.secureHash($H"Password"): db.generateToken(user) else: - respErr"Incorrect username or password.\n" # fails if password is wrong but mentions username to obfuscates if a user exists or not - - var userToken: string - with userToken: - add "[{" - add("\"token\": \"" & user.token & "\"") - add "}]" + respErr "Incorrect username or password.\n" # fails if password is wrong but mentions username to obfuscates if a user exists or not info "Replaced token.\n" & reqInfo - resp Http200, userToken & "\n", "application/json" + resp200 user.token.toJson() diff --git a/src/routes/delete.nim b/src/routes/delete.nim index 5e1d375..11a825a 100644 --- a/src/routes/delete.nim +++ b/src/routes/delete.nim @@ -1,5 +1,6 @@ -import std/[strutils, os, httpclient, strformat, with, logging] +import std/[strutils, os, httpclient, strformat, logging] import jester +import jsony import norm/model import norm/postgres except error import ../types/[users, files] @@ -22,47 +23,45 @@ proc createDeletionRoutes*(cfg: Cfg) = #[ request parameters: token - string - required via header - returns: JSON ]# delete "/api/v1/userCompletely": debug "Endpoint used.\n" & reqInfo var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" + discard waitFor purgeUserFiles(H"Authorization") db.delete(user) info "User deactivated.\n" & reqInfo - resp Http200, "[]\n", "application/json" + resp200 #[ request parameters: token - string - required via header - returns: JSON ]# delete "/api/v1/user": debug "Endpoint used.\n" & reqInfo var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" db.delete(user) info "User account deleted.\n" & reqInfo - resp Http200, "[]\n", "application/json" + resp200 #[ request parameters: token - string - required via header name - string - required via header - returns: JSON ]# delete "/api/v1/file": debug "Endpoint used.\n" & reqInfo var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" var file = newFile() try: @@ -70,31 +69,25 @@ proc createDeletionRoutes*(cfg: Cfg) = except NotFoundError: respErr Http404, "File does not exist.\n" + var fileInfo = getFileInfo(file) + removeFile(file.path) db.delete(file) dec user.fileCount db.update(user) - var userFileCount: string - with userFileCount: - add "[{" - add("\"fileCount\": \"" & $user.fileCount & "\"") - add "}]" - info "Deleted file.\n" & reqInfo - resp Http200, userFileCount & "\n", "application/json" + resp200 fileInfo.toJson() #[ request parameters: token - string - required via header - returns - 200 - deleted all of the user's file from db and filesystem only ]# delete "/api/v1/files": debug "Endpoint used.\n" & reqInfo var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" var listOfFiles = @[newFile()] try: @@ -110,4 +103,4 @@ proc createDeletionRoutes*(cfg: Cfg) = removeDir(cfg.uploadDir & user.username & "/") info "Deleting user's files.\n" & reqInfo - resp Http200, "[]\n", "application/json" + resp200 diff --git a/src/routes/download.nim b/src/routes/download.nim index 9d3fc91..49aaec0 100644 --- a/src/routes/download.nim +++ b/src/routes/download.nim @@ -1,5 +1,6 @@ import std/[strutils, logging] import jester +import jsony import norm/postgres except error import ../types/[users, files] import ../[database, helpers] @@ -17,7 +18,7 @@ proc createDownloadRoutes*() = var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" var file = newFile() try: @@ -31,26 +32,19 @@ proc createDownloadRoutes*() = #[ request parameters: token - string - required via header - returns: JSON ]# get "/api/v1/listOfAllFiles": debug "Endpoint used.\n" & reqInfo var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" var listOfFiles = @[newFile()] try: db.select(listOfFiles, """"File".owner = $1""", user.id) except NotFoundError: - respErr Http404, "Files does not exist.\n" - - var allFiles: string - - for file in listOfFiles: - allFiles = allFiles & "{" & "\"name\": \"" & file.name & - "\", \"tags\": " & file.tags & "}," - allFiles = "[" & allFiles[0..^2] & "]" # trim last comma + respErr Http404, "No file exists.\n" info "List user's file.\n" & reqInfo - resp Http200, allFiles & "\n", "application/json" + resp200 listOfFiles.toJson() # TODO: create new type without unneeded members, read data to it then resp as json. if all else fails -> edit File type to not include owner json in it? Maybe make user.password private? + diff --git a/src/routes/update.nim b/src/routes/update.nim index e40a193..70ca78c 100644 --- a/src/routes/update.nim +++ b/src/routes/update.nim @@ -1,5 +1,6 @@ -import std/[strutils, os, with, logging] +import std/[strutils, os, logging] import jester +import jsony import norm/postgres except error import ../types/[users, files] import ../[database, helpers] @@ -17,7 +18,7 @@ proc createUpdateRoutes*() = debug "Endpoint used.\n" & reqInfo var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" let oldName = H"Old name" @@ -44,12 +45,5 @@ proc createUpdateRoutes*() = file.name = newName db.update(file) - var fileInfo: string - with fileInfo: - add "[{" - add("\"name\": \"" & file.name & "\",") - add("\"tags\": \"" & file.tags & "\"") - add "}]" - info "File renamed.\n" & reqInfo - resp Http200, fileInfo & "\n", "application/json" + resp200 getFileInfo(file).toJson() diff --git a/src/routes/upload.nim b/src/routes/upload.nim index 0cbacbf..7558342 100644 --- a/src/routes/upload.nim +++ b/src/routes/upload.nim @@ -1,5 +1,6 @@ -import std/[strutils, os, json, with, logging] +import std/[strutils, os, json, logging] import jester +import jsony import norm/model import norm/postgres except error import ../types/[users, files] @@ -13,14 +14,13 @@ proc createUploadRoutes*(cfg: Cfg) = file - string/binary - required token - string - required via header tags - JSON - optinal - returns: JSON ]# post "/api/v1/newFile": debug "Endpoint used.\n" & reqInfo # fills the new `user` var with saved user data from database var user = newUser() if not db.validToken(user, H"Authorization"): - resp Http403, "Invalid token.\n" + respErr "Invalid token.\n" # pull request form data arguments let fileData = request.formData["file"].body @@ -55,11 +55,6 @@ proc createUploadRoutes*(cfg: Cfg) = # write the file from memory writeFile(filePath, fileData) - var userFileCount: string - with userFileCount: - add "[{" - add("\"fileCount\": \"" & $user.fileCount & "\"") - add "}]" info "File uploaded.\n" & reqInfo - resp Http200, userFileCount & "\n", "application/json" + resp200 getFileInfo(file).toJson() diff --git a/src/types/files.nim b/src/types/files.nim index 98bdbb7..e4a36de 100644 --- a/src/types/files.nim +++ b/src/types/files.nim @@ -9,9 +9,17 @@ type File* = ref object of Model name*: string tags*: string #? This is a temporary hack should be `seq[string]` or `JsonNode` instead - # creates a new file object and sets default values, recommended by the norm documentation +type FileInfo* = ref object + name*: string + tags*: string + + # creates a new file object and sets default values, recommended by the norm documentation proc newFile*(user: User = newUser(), path: string = "", name: string = "", tags: string = ""): File = inc user.fileCount debug "Creating new file.\n" File(owner: user, path: path, name: name, tags: tags) + +proc getFileInfo*(file: File = newFile()): FileInfo = + debug "getting file info.\n" + FileInfo(name: file.name, tags: file.tags) diff --git a/tests/test_1.sh b/tests/test_1.sh index ff1e4d7..4f9e66f 100755 --- a/tests/test_1.sh +++ b/tests/test_1.sh @@ -46,7 +46,7 @@ fi; printf "%b\n" "$CLR"; ENDPOINT="/api/v1/newSession" printf "\n%bTest: $ENDPOINT%b\n" "$BLD" "$CLR" -MKUSER; TOKEN=$(curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""/api/v1/newUser" -d "username=$TESTUSER" -d "password=$PASSWORD" -d "email=$TESTUSER@example.xyz" | jq ".[0].token" | tr -d '"') +MKUSER; TOKEN=$(curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""/api/v1/newUser" -d "username=$TESTUSER" -d "password=$PASSWORD" -d "email=$TESTUSER@example.xyz" | jq ".token" | tr -d '"') curl --show-error --fail-with-body --request GET http://"$BINDADDR":"$PORT""$ENDPOINT" \ -H "Authorization: $TOKEN" @@ -59,7 +59,7 @@ fi; printf "%b\n" "$CLR"; ENDPOINT="/api/v1/newFile" printf "\n%bTest: $ENDPOINT%b\n" "$BLD" "$CLR" -MKUSER; TOKEN=$(curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""/api/v1/newUser" -d "username=$TESTUSER" -d "password=$PASSWORD" -d "email=$TESTUSER@example.xyz" | jq ".[0].token" | tr -d '"') +MKUSER; TOKEN=$(curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""/api/v1/newUser" -d "username=$TESTUSER" -d "password=$PASSWORD" -d "email=$TESTUSER@example.xyz" | jq ".token" | tr -d '"') curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""$ENDPOINT" \ -H "Authorization: $TOKEN" -F "file=@image.png" @@ -155,7 +155,7 @@ fi; printf "%b\n" "$CLR"; ENDPOINT="/api/v1/userCompletely" printf "\n%bTest: $ENDPOINT%b\n" "$BLD" "$CLR" -MKUSER; TOKEN=$(curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""/api/v1/newUser" -d "username=$TESTUSER" -d "password=$PASSWORD" -d "email=$TESTUSER@example.xyz" | jq ".[0].token" | tr -d '"') +MKUSER; TOKEN=$(curl --show-error --fail-with-body --request POST http://"$BINDADDR":"$PORT""/api/v1/newUser" -d "username=$TESTUSER" -d "password=$PASSWORD" -d "email=$TESTUSER@example.xyz" | jq ".token" | tr -d '"') curl --show-error --fail-with-body --request DELETE http://"$BINDADDR":"$PORT""$ENDPOINT" \ -H "Authorization: $TOKEN"