Skip to content

Commit

Permalink
Merge pull request #147 from linkernetworks/johnlin/jwt-api
Browse files Browse the repository at this point in the history
JWT POC for API
  • Loading branch information
Hung-Wei Chiu authored Jul 25, 2018
2 parents 17ca9fa + d1dadab commit ce60587
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/server/handler_authenticate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package server

import (
"strings"

response "github.com/linkernetworks/vortex/src/net/http"
"github.com/linkernetworks/vortex/src/web"
)

// TODO move to entity
type UserCredentials struct {
Username string `json:"username"`
Password string `json:"password"`
}

func loginHandler(ctx *web.Context) {
_, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response
user := UserCredentials{}
if err := req.ReadEntity(&user); err != nil {
response.Forbidden(req.Request, resp.ResponseWriter, err)
return
}

// TODO query mongodb to check user account and password
if strings.ToLower(user.Username) != "someone" || user.Password != "p@ssword" {
response.Forbidden(req.Request, resp.ResponseWriter)
return
}

tokenString, err := generateToken(strings.ToLower(user.Username))
if err != nil {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}

resp.WriteEntity(response.ActionResponse{
Error: false,
Message: tokenString,
})
}
20 changes: 20 additions & 0 deletions src/server/jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package server

import (
"time"

"github.com/dgrijalva/jwt-go"
)

func generateToken(userUUID string) (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = jwt.MapClaims{
// issuer of the claim
"exp": time.Now().Add(time.Hour * time.Duration(1)).Unix(),
// issued-at time
"iat": time.Now().Unix(),
// the subject of this token. This is the user associated with the relevant action
"sub": userUUID,
}
return token.SignedString([]byte(SecretKey))
}
13 changes: 13 additions & 0 deletions src/server/jwt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package server

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestGenerateToken(t *testing.T) {
tokenString, err := generateToken("234243353535330")
assert.NotNil(t, tokenString)
assert.NoError(t, err)
}
8 changes: 8 additions & 0 deletions src/server/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func (a *App) AppRoute() *mux.Router {

container.Add(newVersionService(a.ServiceProvider))
container.Add(newUserService(a.ServiceProvider))
container.Add(newAuthenticateService(a.ServiceProvider))
container.Add(newNetworkService(a.ServiceProvider))
container.Add(newStorageService(a.ServiceProvider))
container.Add(newVolumeService(a.ServiceProvider))
Expand All @@ -31,6 +32,7 @@ func (a *App) AppRoute() *mux.Router {
func newVersionService(sp *serviceprovider.Container) *restful.WebService {
webService := new(restful.WebService)
webService.Path("/v1/version").Consumes(restful.MIME_JSON, restful.MIME_JSON).Produces(restful.MIME_JSON, restful.MIME_JSON)
// webService.Filter(validateTokenMiddleware)
webService.Route(webService.GET("/").To(handler.RESTfulServiceHandler(sp, versionHandler)))
return webService
}
Expand All @@ -44,6 +46,12 @@ func newUserService(sp *serviceprovider.Container) *restful.WebService {
webService.Route(webService.GET("/{id}").To(handler.RESTfulServiceHandler(sp, getUserHandler)))
return webService
}
func newAuthenticateService(sp *serviceprovider.Container) *restful.WebService {
webService := new(restful.WebService)
webService.Path("/v1/login").Consumes(restful.MIME_JSON, restful.MIME_JSON).Produces(restful.MIME_JSON, restful.MIME_JSON)
webService.Route(webService.POST("/").To(handler.RESTfulServiceHandler(sp, loginHandler)))
return webService
}

func newNetworkService(sp *serviceprovider.Container) *restful.WebService {
webService := new(restful.WebService)
Expand Down
30 changes: 30 additions & 0 deletions src/server/route_filter.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
package server

import (
"net/http"

"github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
"github.com/emicklei/go-restful"
"github.com/linkernetworks/logger"
)

// FIXME using ldconfig go build to give a secretkey
const (
SecretKey = "linkernetworks"
)

func globalLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
logger.Infof("%s %s", req.Request.Method, req.Request.URL)
chain.ProcessFilter(req, resp)
}

func validateTokenMiddleware(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
token, err := request.ParseFromRequest(req.Request, request.AuthorizationHeaderExtractor,
func(token *jwt.Token) (interface{}, error) {
return []byte(SecretKey), nil
})

if err == nil {
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
// save to requests attributes
req.SetAttribute("UserID", claims["sub"])
chain.ProcessFilter(req, resp)
} else {
resp.WriteHeader(http.StatusUnauthorized)
logger.Infof("Token is not valid")
}
} else {
resp.WriteHeader(http.StatusUnauthorized)
logger.Infof("Unauthorized access to this resource")
}
}
6 changes: 6 additions & 0 deletions vendor/vendor.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
"revision": "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e",
"revisionTime": "2018-03-08T23:13:08Z"
},
{
"checksumSHA1": "SvAnbKinPLfP+DoIB/uHdGCKClE=",
"path": "github.com/dgrijalva/jwt-go/request",
"revision": "0b96aaa707760d6ab28d9b9d1913ff5993328bae",
"revisionTime": "2018-07-19T21:18:23Z"
},
{
"checksumSHA1": "wPbKObbGzS/43nrskRaJVFVEW/A=",
"path": "github.com/ema/qdisc",
Expand Down

0 comments on commit ce60587

Please sign in to comment.