|
@@ -129,9 +129,9 @@ var pages = map[string]Page { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var roles = map[string]int{ |
|
|
var roles = map[string]int{ |
|
|
"guest": 1, |
|
|
|
|
|
"employee": 2, |
|
|
|
|
|
"admin": 3, |
|
|
|
|
|
|
|
|
"User": 1, |
|
|
|
|
|
"Manager": 2, |
|
|
|
|
|
"Admin": 3, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Used to validate claim in JWT token body. Checks if user id is greater than |
|
|
// Used to validate claim in JWT token body. Checks if user id is greater than |
|
@@ -624,6 +624,152 @@ func guard(r *http.Request, required int) bool { |
|
|
return true |
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func queryUsers(db *sql.DB, id int) ( []User, error ) { |
|
|
|
|
|
var users []User |
|
|
|
|
|
var query string |
|
|
|
|
|
var rows *sql.Rows |
|
|
|
|
|
var err error |
|
|
|
|
|
|
|
|
|
|
|
query = `SELECT |
|
|
|
|
|
u.id, |
|
|
|
|
|
u.email, |
|
|
|
|
|
u.first_name, |
|
|
|
|
|
u.last_name, |
|
|
|
|
|
u.branch_id, |
|
|
|
|
|
u.country, |
|
|
|
|
|
u.title, |
|
|
|
|
|
u.status, |
|
|
|
|
|
u.verified, |
|
|
|
|
|
u.last_login, |
|
|
|
|
|
u.role |
|
|
|
|
|
FROM user u WHERE u.id = CASE @e := ? WHEN 0 THEN u.id ELSE @e END |
|
|
|
|
|
` |
|
|
|
|
|
rows, err = db.Query(query, id) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return users, err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
defer rows.Close() |
|
|
|
|
|
|
|
|
|
|
|
for rows.Next() { |
|
|
|
|
|
var user User |
|
|
|
|
|
|
|
|
|
|
|
if err := rows.Scan( |
|
|
|
|
|
&user.Id, |
|
|
|
|
|
&user.Email, |
|
|
|
|
|
&user.FirstName, |
|
|
|
|
|
&user.LastName, |
|
|
|
|
|
&user.BranchId, |
|
|
|
|
|
&user.Country, |
|
|
|
|
|
&user.Title, |
|
|
|
|
|
&user.Status, |
|
|
|
|
|
&user.Verified, |
|
|
|
|
|
&user.LastLogin, |
|
|
|
|
|
&user.Role, |
|
|
|
|
|
) |
|
|
|
|
|
err != nil { |
|
|
|
|
|
return users, err |
|
|
|
|
|
} |
|
|
|
|
|
users = append(users, user) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Prevents runtime panics |
|
|
|
|
|
if len(users) == 0 { return users, errors.New("User not found.") } |
|
|
|
|
|
|
|
|
|
|
|
return users, nil |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func insertUser(db *sql.DB, user User) (User, error){ |
|
|
|
|
|
var query string |
|
|
|
|
|
var row *sql.Row |
|
|
|
|
|
var err error |
|
|
|
|
|
var id int // Inserted user's id |
|
|
|
|
|
|
|
|
|
|
|
query = `INSERT INTO user |
|
|
|
|
|
( |
|
|
|
|
|
email, |
|
|
|
|
|
first_name, |
|
|
|
|
|
last_name, |
|
|
|
|
|
password, |
|
|
|
|
|
created, |
|
|
|
|
|
role, |
|
|
|
|
|
verified, |
|
|
|
|
|
last_login |
|
|
|
|
|
) |
|
|
|
|
|
VALUES (?, ?, ?, sha2(?, 256), NOW(), ?, ?, NOW()) |
|
|
|
|
|
RETURNING id |
|
|
|
|
|
` |
|
|
|
|
|
row = db.QueryRow(query, |
|
|
|
|
|
user.Email, |
|
|
|
|
|
user.FirstName, |
|
|
|
|
|
user.LastName, |
|
|
|
|
|
user.Password, |
|
|
|
|
|
user.Role, |
|
|
|
|
|
user.Verified, |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
err = row.Scan(&id) |
|
|
|
|
|
if err != nil { return User{}, err } |
|
|
|
|
|
|
|
|
|
|
|
users, err := queryUsers(db, id) |
|
|
|
|
|
if err != nil { return User{}, err } |
|
|
|
|
|
|
|
|
|
|
|
return users[0], nil |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func updateUser(user User, db *sql.DB) error { |
|
|
|
|
|
query := ` |
|
|
|
|
|
UPDATE user |
|
|
|
|
|
SET |
|
|
|
|
|
email = CASE @e := ? WHEN '' THEN email ELSE @e END, |
|
|
|
|
|
first_name = CASE @fn := ? WHEN '' THEN first_name ELSE @fn END, |
|
|
|
|
|
last_name = CASE @ln := ? WHEN '' THEN last_name ELSE @ln END, |
|
|
|
|
|
role = CASE @r := ? WHEN '' THEN role ELSE @r END, |
|
|
|
|
|
password = CASE @p := ? WHEN '' THEN password ELSE sha2(@p, 256) END |
|
|
|
|
|
WHERE id = ? |
|
|
|
|
|
` |
|
|
|
|
|
|
|
|
|
|
|
_, err := db.Exec(query, |
|
|
|
|
|
user.Email, |
|
|
|
|
|
user.FirstName, |
|
|
|
|
|
user.LastName, |
|
|
|
|
|
user.Role, |
|
|
|
|
|
user.Password, |
|
|
|
|
|
user.Id, |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func getUser(w http.ResponseWriter, db *sql.DB, r *http.Request) { |
|
|
|
|
|
claims, err := getClaims(r) |
|
|
|
|
|
if err != nil { w.WriteHeader(500); return } |
|
|
|
|
|
users, err := queryUsers(db, claims.Id) |
|
|
|
|
|
if err != nil { w.WriteHeader(422); return } |
|
|
|
|
|
json.NewEncoder(w).Encode(users) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func createUser(w http.ResponseWriter, db *sql.DB, r *http.Request) { |
|
|
|
|
|
var user User |
|
|
|
|
|
err := json.NewDecoder(r.Body).Decode(&user) |
|
|
|
|
|
if err != nil { http.Error(w, "Invalid fields.", 422); return } |
|
|
|
|
|
|
|
|
|
|
|
_, err = mail.ParseAddress(user.Email) |
|
|
|
|
|
if err != nil { http.Error(w, "Invalid email.", 422); return } |
|
|
|
|
|
|
|
|
|
|
|
if roles[user.Role] == 0 { |
|
|
|
|
|
http.Error(w, "Invalid role.", 422) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
user, err = insertUser(db, user) |
|
|
|
|
|
if err != nil { http.Error(w, "Error creating user.", 422); return } |
|
|
|
|
|
|
|
|
|
|
|
json.NewEncoder(w).Encode(user) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func api(w http.ResponseWriter, r *http.Request) { |
|
|
func api(w http.ResponseWriter, r *http.Request) { |
|
|
var args []string |
|
|
var args []string |
|
|
|
|
|
|
|
@@ -649,10 +795,10 @@ func api(w http.ResponseWriter, r *http.Request) { |
|
|
r.Method == http.MethodGet && guard(r, 1): |
|
|
r.Method == http.MethodGet && guard(r, 1): |
|
|
getToken(w, db, r) |
|
|
getToken(w, db, r) |
|
|
case match(p, "/api/users", &args) && // Array of all users |
|
|
case match(p, "/api/users", &args) && // Array of all users |
|
|
r.Method == http.MethodGet && guard(r, 2): |
|
|
|
|
|
|
|
|
r.Method == http.MethodGet && guard(r, 3): |
|
|
getUsers(w, db, r) |
|
|
getUsers(w, db, r) |
|
|
case match(p, "/api/user", &args) && |
|
|
case match(p, "/api/user", &args) && |
|
|
r.Method == http.MethodGet, && guard(r, 1): |
|
|
|
|
|
|
|
|
r.Method == http.MethodGet && guard(r, 1): |
|
|
getUser(w, db, r) |
|
|
getUser(w, db, r) |
|
|
case match(p, "/api/user", &args) && |
|
|
case match(p, "/api/user", &args) && |
|
|
r.Method == http.MethodPost && |
|
|
r.Method == http.MethodPost && |
|
@@ -670,54 +816,6 @@ func api(w http.ResponseWriter, r *http.Request) { |
|
|
r.Method == http.MethodDelete && |
|
|
r.Method == http.MethodDelete && |
|
|
guard(r, 3): |
|
|
guard(r, 3): |
|
|
deleteUser(w, db, r) |
|
|
deleteUser(w, db, r) |
|
|
case match(p, "/api/batch", &args) && |
|
|
|
|
|
r.Method == http.MethodGet && |
|
|
|
|
|
guard(r, 1): |
|
|
|
|
|
getBatch(w, db, r) |
|
|
|
|
|
case match(p, "/api/batch", &args) && |
|
|
|
|
|
r.Method == http.MethodPost && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
openBatch(w, db, r) |
|
|
|
|
|
case match(p, "/api/batch", &args) && |
|
|
|
|
|
r.Method == http.MethodPatch && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
closeBatch(w, db, r) |
|
|
|
|
|
case match(p, "/api/client", &args) && |
|
|
|
|
|
r.Method == http.MethodGet && |
|
|
|
|
|
guard(r, 1): |
|
|
|
|
|
getClient(w, db, r) |
|
|
|
|
|
case match(p, "/api/client", &args) && |
|
|
|
|
|
r.Method == http.MethodPost && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
createClient(w, db, r) |
|
|
|
|
|
case match(p, "/api/client", &args) && |
|
|
|
|
|
r.Method == http.MethodPatch && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
patchClient(w, db, r) |
|
|
|
|
|
case match(p, "/api/client", &args) && |
|
|
|
|
|
r.Method == http.MethodDelete && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
deleteClient(w, db, r) |
|
|
|
|
|
case match(p, "/api/ticket", &args) && |
|
|
|
|
|
r.Method == http.MethodPost && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
openTicket(w, db, r) |
|
|
|
|
|
case match(p, "/api/ticket", &args) && |
|
|
|
|
|
r.Method == http.MethodPatch && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
closeTicket(w, db, r) |
|
|
|
|
|
case match(p, "/api/ticket", &args) && |
|
|
|
|
|
r.Method == http.MethodDelete && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
voidTicket(w, db, r) |
|
|
|
|
|
case match(p, "/api/report/batch", &args) && |
|
|
|
|
|
r.Method == http.MethodGet && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
reportBatch(w, db, r) |
|
|
|
|
|
case match(p, "/api/report/summary", &args) && |
|
|
|
|
|
r.Method == http.MethodPost && |
|
|
|
|
|
guard(r, 2): |
|
|
|
|
|
reportSummary(w, db, r) |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
db.Close() |
|
|
db.Close() |
|
|