303 lines
6.6 KiB
Go
303 lines
6.6 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
"net/mail"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/leandrofars/oktopus/internal/api/auth"
|
|
"github.com/leandrofars/oktopus/internal/db"
|
|
"github.com/leandrofars/oktopus/internal/utils"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
func (a *Api) retrieveUsers(w http.ResponseWriter, r *http.Request) {
|
|
users, err := a.db.FindAllUsers()
|
|
if err != nil {
|
|
log.Println(err)
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
for _, x := range users {
|
|
objectID, ok := x["_id"].(primitive.ObjectID)
|
|
if ok {
|
|
creationTime := objectID.Timestamp()
|
|
x["createdAt"] = creationTime.Format("02/01/2006")
|
|
}
|
|
delete(x, "password")
|
|
}
|
|
|
|
err = json.NewEncoder(w).Encode(users)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
func (a *Api) registerUser(w http.ResponseWriter, r *http.Request) {
|
|
|
|
tokenString := r.Header.Get("Authorization")
|
|
if tokenString == "" {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
email, err := auth.ValidateToken(tokenString)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
//Check if user which is requesting creation has the necessary privileges
|
|
rUser, err := a.db.FindUser(email)
|
|
if rUser.Level != db.AdminUser {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
var user db.User
|
|
err = json.NewDecoder(r.Body).Decode(&user)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
user.Level = db.NormalUser
|
|
|
|
if err := user.HashPassword(user.Password); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if user.Email == "" || user.Password == "" || !valid(user.Email) {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if err := a.db.RegisterUser(user); err != nil {
|
|
if err == db.ErrorUserExists {
|
|
w.WriteHeader(http.StatusConflict)
|
|
w.Write([]byte("User with this email already exists"))
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
func valid(email string) bool {
|
|
_, err := mail.ParseAddress(email)
|
|
return err == nil
|
|
}
|
|
|
|
func (a *Api) deleteUser(w http.ResponseWriter, r *http.Request) {
|
|
tokenString := r.Header.Get("Authorization")
|
|
if tokenString == "" {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
email, err := auth.ValidateToken(tokenString)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
//Check if user which is requesting deletion has the necessary privileges
|
|
rUser, err := a.db.FindUser(email)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
userEmail := mux.Vars(r)["user"]
|
|
|
|
if rUser.Email == userEmail || (rUser.Level == db.AdminUser) { //Admin can delete any account
|
|
if err := a.db.DeleteUser(userEmail); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(err)
|
|
return
|
|
}
|
|
} else {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
}
|
|
}
|
|
|
|
func (a *Api) changePassword(w http.ResponseWriter, r *http.Request) {
|
|
tokenString := r.Header.Get("Authorization")
|
|
if tokenString == "" {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
email, err := auth.ValidateToken(tokenString)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
userToChangePasswd := mux.Vars(r)["user"]
|
|
if userToChangePasswd != "" && userToChangePasswd != email {
|
|
rUser, _ := a.db.FindUser(email)
|
|
if rUser.Level != db.AdminUser {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
return
|
|
}
|
|
email = userToChangePasswd
|
|
}
|
|
|
|
var user db.User
|
|
err = json.NewDecoder(r.Body).Decode(&user)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
utils.MarshallEncoder(err, w)
|
|
return
|
|
}
|
|
user.Email = email
|
|
|
|
if err := user.HashPassword(user.Password); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err := a.db.UpdatePassword(user); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
}
|
|
|
|
func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
|
|
|
|
tokenString := r.Header.Get("Authorization")
|
|
if tokenString == "" {
|
|
users, err := a.db.FindAllUsers()
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
utils.MarshallEncoder(err, w)
|
|
}
|
|
|
|
if !adminUserExists(users) {
|
|
var user db.User
|
|
err = json.NewDecoder(r.Body).Decode(&user)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
user.Level = db.AdminUser
|
|
|
|
if err := user.HashPassword(user.Password); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err := a.db.RegisterUser(user); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
} else {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
email, err := auth.ValidateToken(tokenString)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
//Check if user which is requesting creation has the necessary privileges
|
|
rUser, err := a.db.FindUser(email)
|
|
if rUser.Level != db.AdminUser {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
return
|
|
}
|
|
|
|
var user db.User
|
|
err = json.NewDecoder(r.Body).Decode(&user)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
user.Level = db.AdminUser
|
|
|
|
if err := user.HashPassword(user.Password); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err := a.db.RegisterUser(user); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
func adminUserExists(users []map[string]interface{}) bool {
|
|
|
|
if len(users) == 0 {
|
|
return false
|
|
}
|
|
|
|
for _, x := range users {
|
|
if db.UserLevels(x["level"].(int32)) == db.AdminUser {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (a *Api) adminUserExists(w http.ResponseWriter, r *http.Request) {
|
|
|
|
users, err := a.db.FindAllUsers()
|
|
if err != nil {
|
|
log.Println(err)
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
adminExits := adminUserExists(users)
|
|
json.NewEncoder(w).Encode(adminExits)
|
|
return
|
|
}
|
|
|
|
type TokenRequest struct {
|
|
Email string `json:"email"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
func (a *Api) generateToken(w http.ResponseWriter, r *http.Request) {
|
|
var tokenReq TokenRequest
|
|
|
|
err := json.NewDecoder(r.Body).Decode(&tokenReq)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
user, err := a.db.FindUser(tokenReq.Email)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
json.NewEncoder(w).Encode("Invalid Credentials")
|
|
return
|
|
}
|
|
|
|
credentialError := user.CheckPassword(tokenReq.Password)
|
|
if credentialError != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
json.NewEncoder(w).Encode("Invalid Credentials")
|
|
return
|
|
}
|
|
|
|
token, err := auth.GenerateJWT(user.Email, user.Name)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Add("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(token)
|
|
return
|
|
}
|