diff --git a/logic/db_types/user.go b/logic/db_types/user.go index 89a4785..f29e62a 100644 --- a/logic/db_types/user.go +++ b/logic/db_types/user.go @@ -5,6 +5,13 @@ import ( "errors" ) +type UserType int + +const ( + User_Normal UserType = iota + 1 + User_Admin +) + type User struct { Id string Username string diff --git a/logic/utils/handler.go b/logic/utils/handler.go index 45028e1..586e05b 100644 --- a/logic/utils/handler.go +++ b/logic/utils/handler.go @@ -471,11 +471,19 @@ func (x Handle) createContext(handler *Handle, mode AnswerType, r *http.Request) Prefix: r.URL.Path, }) - for _, r := range r.Cookies() { - if r.Name == "auth" { - token = &r.Value - } - } + if mode != JSON { + for _, r := range r.Cookies() { + if r.Name == "auth" { + token = &r.Value + } + } + } else { + t := r.Header.Get("token") + if t != "" { + token = &t + } + } + // TODO check that the token is still valid @@ -512,14 +520,19 @@ func Redirect(path string, mode AnswerType, w http.ResponseWriter, r *http.Reque } func Logoff(mode AnswerType, w http.ResponseWriter, r *http.Request) { - // Delete cookie - cookie := &http.Cookie{ - Name: "auth", - Value: "", - Expires: time.Unix(0, 0), - } - http.SetCookie(w, cookie) - Redirect("/login", mode, w, r) + if (mode == JSON) { + w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte("\"Not Authorized\"")) + } else { + // Delete cookie + cookie := &http.Cookie{ + Name: "auth", + Value: "", + Expires: time.Unix(0, 0), + } + http.SetCookie(w, cookie) + Redirect("/login", mode, w, r) + } } func notAuth(mode AnswerType, w http.ResponseWriter, r *http.Request) { diff --git a/users.go b/users.go index b0150e1..5c31f71 100644 --- a/users.go +++ b/users.go @@ -11,6 +11,7 @@ import ( "golang.org/x/crypto/bcrypt" dbtypes "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types" + "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils" . "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils" ) @@ -168,52 +169,52 @@ func usersEndpints(db *sql.DB, handle *Handle) { return err } - if len(dat.Username) == 0 || len(dat.Password) == 0 || len(dat.Email) == 0 { - return c.SendJSONStatus(w, http.StatusBadRequest, "Please provide a valid json"); - } + if len(dat.Username) == 0 || len(dat.Password) == 0 || len(dat.Email) == 0 { + return c.SendJSONStatus(w, http.StatusBadRequest, "Please provide a valid json") + } rows, err := db.Query("select username, email from users where username=$1 or email=$2;", dat.Username, dat.Email) - if err != nil { - return c.Error500(err); - } + if err != nil { + return c.Error500(err) + } defer rows.Close() if rows.Next() { var db_username string var db_email string err = rows.Scan(&db_username, &db_email) - if err != nil { - return c.Error500(err) - } - if (db_email == dat.Email) { - return c.SendJSONStatus(w, http.StatusBadRequest, "Email already in use!") - } - if (db_username == dat.Username) { - return c.SendJSONStatus(w, http.StatusBadRequest, "Username already in use!") - } - panic("Unrechable") + if err != nil { + return c.Error500(err) + } + if db_email == dat.Email { + return c.SendJSONStatus(w, http.StatusBadRequest, "Email already in use!") + } + if db_username == dat.Username { + return c.SendJSONStatus(w, http.StatusBadRequest, "Username already in use!") + } + panic("Unrechable") } if len([]byte(dat.Password)) > 68 { - return c.JsonBadRequest(w, "Password is to long!") + return c.JsonBadRequest(w, "Password is to long!") } salt := generateSalt() hash_password, err := hashPassword(dat.Password, salt) if err != nil { - return c.Error500(err) + return c.Error500(err) } _, err = db.Exec("insert into users (username, email, salt, password) values ($1, $2, $3, $4);", dat.Username, dat.Email, salt, hash_password) - if err != nil { - return c.Error500(err) - } + if err != nil { + return c.Error500(err) + } // TODO Give this to the generateToken function token, login := generateToken(db, dat.Email, dat.Password) - if !login { - return c.SendJSONStatus(w, 500, "Could not login after creatting account please try again later") - } + if !login { + return c.SendJSONStatus(w, 500, "Could not login after creatting account please try again later") + } user, err := dbtypes.UserFromToken(c.Db, token) if err != nil { @@ -335,6 +336,87 @@ func usersEndpints(db *sql.DB, handle *Handle) { return nil }) + // Handles updating users + handle.Post("/user/info", func(w http.ResponseWriter, r *http.Request, c *Context) *Error { + if !CheckAuthLevel(int(dbtypes.User_Normal), w, r, c) { + return nil + } + if c.Mode != JSON { + return c.Error500(nil) + } + + type UserData struct { + Id string `json:"id"` + Email string `json:"email"` + } + + var dat UserData + + if err := c.ToJSON(r, &dat); err != nil { + return err + } + + if dat.Id != c.User.Id && c.User.UserType != int(dbtypes.User_Admin) { + return c.SendJSONStatus(w, 401, "You need to be an admin to update another users account") + } + + if dat.Id != c.User.Id { + var data struct { + Id string + } + + err := utils.GetDBOnce(c, &data, "users where id=$1", dat.Id) + if err == NotFoundError { + return c.JsonBadRequest(w, "User does not exist") + } else if err != nil { + return c.Error500(err) + } + } + + var data struct { + Id string + } + + err := utils.GetDBOnce(c, &data, "users where email=$1", dat.Email) + if err != nil && err != NotFoundError { + return c.Error500(err) + } + + if err != NotFoundError { + if data.Id == dat.Id { + return c.JsonBadRequest(w, "Email is the name as the previous one!") + } else { + return c.JsonBadRequest(w, "Email already in use") + } + } + + _, err = c.Db.Exec("update users set email=$2 where id=$1", dat.Id, dat.Email) + if err != nil { + return c.Error500(err) + } + + var user struct { + Id string + Username string + Email string + User_Type int + } + + err = utils.GetDBOnce(c, &user, "users where id=$1", dat.Id) + if err != nil { + return c.Error500(err) + } + + toReturnUser := dbtypes.User{ + Id: user.Id, + Username: user.Username, + Email: user.Email, + UserType: user.User_Type, + } + + return c.SendJSON(w, toReturnUser) + }) + handle.Post("/user/info/email", func(w http.ResponseWriter, r *http.Request, c *Context) *Error { if !CheckAuthLevel(1, w, r, c) { return nil @@ -367,7 +449,44 @@ func usersEndpints(db *sql.DB, handle *Handle) { return nil } if c.Mode == JSON { - return c.Error500(nil) + + var dat struct { + Old_Password string `json:"old_password"` + Password string `json:"password"` + Password2 string `json:"password2"` + } + + if err := c.ToJSON(r, &dat); err != nil { + return err + } + + if dat.Password == "" { + return c.JsonBadRequest(w, "Password can not be empty") + } + + if dat.Password != dat.Password2 { + return c.JsonBadRequest(w, "New passwords did not match") + } + + c.Logger.Warn("test", "dat", dat) + + _, login := generateToken(db, c.User.Email, dat.Old_Password) + if !login { + return c.JsonBadRequest(w, "Password is incorrect"); + } + + salt := generateSalt() + hash_password, err := hashPassword(dat.Password, salt) + if err != nil { + return c.Error500(err) + } + + _, err = db.Exec("update users set salt=$1, password=$2 where id=$3", salt, hash_password, c.User.Id) + if err != nil { + return c.Error500(err) + } + + return c.SendJSON(w, c.User.Id) } r.ParseForm() diff --git a/webpage/src/lib/FileUpload.svelte b/webpage/src/lib/FileUpload.svelte new file mode 100644 index 0000000..c3e1090 --- /dev/null +++ b/webpage/src/lib/FileUpload.svelte @@ -0,0 +1,43 @@ + + +
+ + +
diff --git a/webpage/src/lib/MessageSimple.svelte b/webpage/src/lib/MessageSimple.svelte new file mode 100644 index 0000000..86d1d2e --- /dev/null +++ b/webpage/src/lib/MessageSimple.svelte @@ -0,0 +1,52 @@ + + + + +{#if message} +
+ {message} +
+{/if} diff --git a/webpage/src/routes/models/+page.svelte b/webpage/src/routes/models/+page.svelte new file mode 100644 index 0000000..f19c30d --- /dev/null +++ b/webpage/src/routes/models/+page.svelte @@ -0,0 +1,59 @@ + + + + + Models + + + +
+ {#if list.length > 0} +
+

My Models

+
+ + New + +
+ + + + + + + + + {#each list as item} + + + + + {/each} + +
+ Name + + +
+ {item.name} + + + Edit + +
+ {:else} +

+ You don't have any models +

+
+ + Create a new model + +
+ {/if} +
diff --git a/webpage/src/routes/models/add/+page.svelte b/webpage/src/routes/models/add/+page.svelte new file mode 100644 index 0000000..c8cf3d8 --- /dev/null +++ b/webpage/src/routes/models/add/+page.svelte @@ -0,0 +1,80 @@ + + + + Create new Model + + +
+

+ Create new Model +

+
+
+ + + +
+
+ +
+ Please provide a base image.
+ This image is a sample of the images that you are going to classfiy. +
+ + + + Upload image + +
+ + Image selected + +
+
+
+ + {#await buttonClicked} +
+ File Uploading +
+ {:then} + + {/await} + +
+ + diff --git a/webpage/src/routes/user/info/+page.svelte b/webpage/src/routes/user/info/+page.svelte new file mode 100644 index 0000000..67cb796 --- /dev/null +++ b/webpage/src/routes/user/info/+page.svelte @@ -0,0 +1,129 @@ + + + + User Info + + +
+
+

User Infomation

+
+
+ + +
+ + + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + +
+
+ + diff --git a/webpage/src/styles/app.css b/webpage/src/styles/app.css index 50800a7..4fd3e93 100644 --- a/webpage/src/styles/app.css +++ b/webpage/src/styles/app.css @@ -37,6 +37,10 @@ button { } } +a.button { + text-decoration: none; +} + .flex { display: flex; } diff --git a/webpage/static/imgs/upload-icon.png b/webpage/static/imgs/upload-icon.png new file mode 100644 index 0000000..88e26b8 Binary files /dev/null and b/webpage/static/imgs/upload-icon.png differ