Skip to content
Snippets Groups Projects
Commit 4d3292e1 authored by meskio's avatar meskio :tent:
Browse files

Add admin authentication

parent acadd492
No related branches found
No related tags found
No related merge requests found
......@@ -36,21 +36,22 @@ func Init(dbPath string, signKey string, r *mux.Router) error {
r.HandleFunc("/signin", a.SignIn).Methods("POST")
r.HandleFunc("/member", a.auth(a.ListMembers)).Methods("GET")
r.HandleFunc("/member", a.auth(a.AddMember)).Methods("POST")
r.HandleFunc("/member/{num:[0-9]+}", a.auth(a.GetMember)).Methods("GET")
r.HandleFunc("/member/{num:[0-9]+}", a.auth(a.UpdateMember)).Methods("PUT")
r.HandleFunc("/member/{num:[0-9]+}", a.auth(a.DeleteMember)).Methods("DELETE")
r.HandleFunc("/member/{num:[0-9]+}/purchase", a.auth(a.GetMemberTransactions)).Methods("GET")
r.HandleFunc("/member", a.authAdmin(a.ListMembers)).Methods("GET")
r.HandleFunc("/member", a.authAdmin(a.AddMember)).Methods("POST")
r.HandleFunc("/member/me", a.authNum(a.getMemberNum)).Methods("GET")
r.HandleFunc("/member/{num:[0-9]+}", a.authAdmin(a.GetMember)).Methods("GET")
r.HandleFunc("/member/{num:[0-9]+}", a.authAdmin(a.UpdateMember)).Methods("PUT")
r.HandleFunc("/member/{num:[0-9]+}", a.authAdmin(a.DeleteMember)).Methods("DELETE")
r.HandleFunc("/member/{num:[0-9]+}/purchase", a.authAdmin(a.GetMemberTransactions)).Methods("GET")
r.HandleFunc("/product", a.auth(a.ListProducts)).Methods("GET")
r.HandleFunc("/product", a.auth(a.AddProduct)).Methods("POST")
r.HandleFunc("/product", a.authAdmin(a.AddProduct)).Methods("POST")
r.HandleFunc("/product/{code:[0-9]+}", a.auth(a.GetProduct)).Methods("GET")
r.HandleFunc("/product/{code:[0-9]+}", a.auth(a.UpdateProduct)).Methods("PUT")
r.HandleFunc("/product/{code:[0-9]+}", a.auth(a.DeleteProduct)).Methods("DELETE")
r.HandleFunc("/product/{code:[0-9]+}", a.authAdmin(a.UpdateProduct)).Methods("PUT")
r.HandleFunc("/product/{code:[0-9]+}", a.authAdmin(a.DeleteProduct)).Methods("DELETE")
r.HandleFunc("/transaction", a.auth(a.ListTransactions)).Methods("GET")
r.HandleFunc("/transaction/{id:[0-9]+}", a.auth(a.GetTransaction)).Methods("GET")
r.HandleFunc("/transaction/{id:[0-9]+}", a.authNumRole(a.GetTransaction)).Methods("GET")
r.HandleFunc("/transaction/mine", a.authNum(a.getTransactionsByMember)).Methods("GET")
r.HandleFunc("/purchase", a.authNum(a.AddPurchase)).Methods("POST")
......
......@@ -75,7 +75,6 @@ func (a *api) authNum(fn func(int, http.ResponseWriter, *http.Request)) func(htt
token := req.Header.Get("x-authentication")
ok, claims := a.validateToken(token)
if !ok {
log.Print("foo")
w.WriteHeader(http.StatusUnauthorized)
return
}
......@@ -88,6 +87,45 @@ func (a *api) authNum(fn func(int, http.ResponseWriter, *http.Request)) func(htt
}
}
func (a *api) authAdmin(fn func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
token := req.Header.Get("x-authentication")
ok, claims := a.validateToken(token)
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
role, ok := claims["role"].(string)
if !ok || role != "admin" {
w.WriteHeader(http.StatusUnauthorized)
return
}
fn(w, req)
}
}
func (a *api) authNumRole(fn func(int, string, http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
token := req.Header.Get("x-authentication")
ok, claims := a.validateToken(token)
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
num, ok := claims["num"].(float64)
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
role, ok := claims["role"].(string)
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
fn(int(num), role, w, req)
}
}
func (a *api) newToken(num int, role string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"num": num,
......
......@@ -15,6 +15,7 @@ func TestSignIn(t *testing.T) {
}
member.Num = 10
member.Name = "foo"
member.Role = "admin"
member.Password = "password"
resp := tapi.do("POST", "/member", member, nil)
if resp.StatusCode != http.StatusCreated {
......
......@@ -4,6 +4,7 @@ import (
"encoding/json"
"log"
"net/http"
"strconv"
"github.com/gorilla/mux"
"gorm.io/gorm"
......@@ -81,14 +82,19 @@ func (a *api) ListMembers(w http.ResponseWriter, req *http.Request) {
func (a *api) GetMember(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
num, _ := strconv.Atoi(vars["num"])
a.getMemberNum(num, w, req)
}
func (a *api) getMemberNum(num int, w http.ResponseWriter, req *http.Request) {
var member Member
err := a.db.Where("num = ?", vars["num"]).First(&member).Error
err := a.db.Where("num = ?", num).First(&member).Error
if err != nil {
if err.Error() == "record not found" {
w.WriteHeader(http.StatusNotFound)
return
}
log.Printf("Can't get member %s: %v", vars["num"], err)
log.Printf("Can't get member %d: %v", num, err)
w.WriteHeader(http.StatusInternalServerError)
return
}
......
......@@ -42,7 +42,7 @@ func (a *api) ListTransactions(w http.ResponseWriter, req *http.Request) {
}
}
func (a *api) GetTransaction(w http.ResponseWriter, req *http.Request) {
func (a *api) GetTransaction(num int, role string, w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
var transaction Transaction
err := a.db.Preload("Purchase.Product").
......@@ -57,6 +57,12 @@ func (a *api) GetTransaction(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
return
}
if transaction.MemberNum != num && role != "admin" {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(transaction)
......
......@@ -19,7 +19,7 @@ class Dashboard extends React.Component {
render() {
return (
<Fetcher
url={"/api/member/"+this.context.num.toString()}
url={"/api/member/me"}
onFetch={member => this.setState({ balance: member.balance, name: member.name})} >
<Container>
<Row>
......
......@@ -13,7 +13,6 @@ function Head(props) {
<Nav className="mr-auto">
<Nav.Link href="/">Dashboard</Nav.Link>
<Nav.Link href="/products">Productos</Nav.Link>
<Nav.Link href="/members">Socias</Nav.Link>
</Nav>
<Form inline>
<Button
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment