Working on securing routes and adding auth levels.
This commit is contained in:
parent
f912a434b5
commit
ea73ecedb9
11 changed files with 141 additions and 51 deletions
30
api/auth.go
30
api/auth.go
|
@ -5,7 +5,6 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
@ -50,35 +49,6 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func serveToken(w http.ResponseWriter, r *http.Request) error {
|
||||
t := jwt.New(jwt.GetSigningMethod("RS256"))
|
||||
|
||||
// Set our claims
|
||||
t.Claims["AccessToken"] = "level1"
|
||||
t.Claims["CustomUserInfo"] = struct {
|
||||
Name string
|
||||
Kind string
|
||||
}{"mrdillon", "human"}
|
||||
|
||||
// Set the expire time
|
||||
// See http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4
|
||||
t.Claims["exp"] = time.Now().Add(time.Minute * 1).Unix()
|
||||
tokenString, err := t.SignedString(signKey)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return errWhileSigningToken
|
||||
}
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: tokenName,
|
||||
Value: tokenString,
|
||||
Path: "/",
|
||||
RawExpires: "0",
|
||||
})
|
||||
|
||||
return writeJSON(w, Message{"success"})
|
||||
}
|
||||
|
||||
type authHandler func(http.ResponseWriter, *http.Request) error
|
||||
|
||||
// Only accessible with a valid token
|
||||
|
|
|
@ -20,8 +20,9 @@ func Handler() *mux.Router {
|
|||
m.Get(router.User).Handler(handler(serveUser))
|
||||
m.Get(router.CreateUser).Handler(handler(serveCreateUser))
|
||||
m.Get(router.Users).Handler(handler(serveUsers))
|
||||
m.Get(router.GetToken).Handler(handler(serveAuthenticateUser))
|
||||
|
||||
m.Get(router.Genus).Handler(handler(serveGenus))
|
||||
m.Get(router.Genus).Handler(authHandler(serveGenus))
|
||||
m.Get(router.CreateGenus).Handler(handler(serveCreateGenus))
|
||||
m.Get(router.Genera).Handler(handler(serveGenera))
|
||||
m.Get(router.UpdateGenus).Handler(handler(serveUpdateGenus))
|
||||
|
@ -69,9 +70,6 @@ func Handler() *mux.Router {
|
|||
m.Get(router.UpdateMeasurement).Handler(handler(serveUpdateMeasurement))
|
||||
m.Get(router.DeleteMeasurement).Handler(handler(serveDeleteMeasurement))
|
||||
|
||||
m.Get(router.GetToken).Handler(handler(serveToken))
|
||||
m.Get(router.Restricted).Handler(authHandler(restrictedHandler))
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ import (
|
|||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
|
||||
"github.com/thermokarst/bactdb/datastore"
|
||||
"github.com/thermokarst/bactdb/models"
|
||||
|
@ -15,13 +17,20 @@ func init() {
|
|||
}
|
||||
|
||||
var (
|
||||
serveMux = http.NewServeMux()
|
||||
httpClient = http.Client{Transport: (*muxTransport)(serveMux)}
|
||||
apiClient = models.NewClient(&httpClient)
|
||||
serveMux = http.NewServeMux()
|
||||
cookieJar, _ = cookiejar.New(nil)
|
||||
httpClient = http.Client{
|
||||
Transport: (*muxTransport)(serveMux),
|
||||
Jar: cookieJar,
|
||||
}
|
||||
apiClient = models.NewClient(&httpClient)
|
||||
)
|
||||
|
||||
func setup() {
|
||||
store = datastore.NewMockDatastore()
|
||||
resp, _ := httpClient.PostForm(apiClient.BaseURL.String()+"authenticate/",
|
||||
url.Values{"username": {"test_user"}, "password": {"password"}})
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
type muxTransport http.ServeMux
|
||||
|
|
30
api/users.go
30
api/users.go
|
@ -3,7 +3,9 @@ package api
|
|||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"net/http"
|
||||
|
@ -59,3 +61,31 @@ func serveUsers(w http.ResponseWriter, r *http.Request) error {
|
|||
|
||||
return writeJSON(w, users)
|
||||
}
|
||||
|
||||
func serveAuthenticateUser(w http.ResponseWriter, r *http.Request) error {
|
||||
username := r.FormValue("username")
|
||||
password := r.FormValue("password")
|
||||
|
||||
auth_level, err := store.Users.Authenticate(username, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t := jwt.New(jwt.GetSigningMethod("RS256"))
|
||||
t.Claims["AccessToken"] = auth_level
|
||||
t.Claims["exp"] = time.Now().Add(time.Minute * 1).Unix()
|
||||
tokenString, err := t.SignedString(signKey)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return errWhileSigningToken
|
||||
}
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: tokenName,
|
||||
Value: tokenString,
|
||||
Path: "/",
|
||||
RawExpires: "0",
|
||||
})
|
||||
|
||||
return writeJSON(w, auth_level)
|
||||
}
|
||||
|
|
|
@ -94,3 +94,29 @@ func TestUser_List(t *testing.T) {
|
|||
t.Errorf("got users %+v but wanted users %+v", users, wantUsers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUser_Authenticate(t *testing.T) {
|
||||
setup()
|
||||
|
||||
test_user := newUser()
|
||||
test_user.Username = "test_user"
|
||||
|
||||
calledAuthenticate := false
|
||||
store.Users.(*models.MockUsersService).Authenticate_ = func(username string, password string) (*string, error) {
|
||||
calledAuthenticate = true
|
||||
auth_level := "read"
|
||||
return &auth_level, nil
|
||||
}
|
||||
|
||||
auth_level, err := apiClient.Users.Authenticate(test_user.Username, "password")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !calledAuthenticate {
|
||||
t.Error("!calledAuthenticate")
|
||||
}
|
||||
if *auth_level != "read" {
|
||||
t.Errorf("got auth level %+v but wanted read", *auth_level)
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue