Skip to content

Commit 4bbe9bc

Browse files
committed
updates
1 parent f3d046b commit 4bbe9bc

28 files changed

+966
-624
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ A complete standalone Oauth2 Server RFC 6749 implementation written in Golang an
88
GoAuth2 is an Oauth2 server implementation written in Golang. Currently authorization code,
99
implicit, and client credentials grant, and password grant types are supported.
1010

11-
GoAuth2 issues an enhanced JWT token that can be used to secure individual REST endpoints for users using roles. REST endpoints can be coded to validate the JWT token using the user's role.
11+
GoAuth2 issues a compressed enhanced JWT token that can be used to secure individual REST endpoints for users using roles. REST endpoints can be coded to validate the JWT token using the user's role. There is also a access token REST service that can validate a compressed token. Token compression can be turned off at startup if desired.
1212

1313
### GoAuth2 will provide the security infrastructure for the new Ulbora Labs eCommerce Platform project, 66GoCart.
1414
#### (66GoCart is an eCommerce Platform server solution written in golang that provides REST endpoints for backend operations. 66GoCart frontend soltutions can be written in golang or any other language.)

compresstoken/compressToken.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//Package compresstoken ...
2+
package compresstoken
3+
4+
import (
5+
"bytes"
6+
"compress/flate"
7+
"compress/zlib"
8+
"encoding/base64"
9+
"io"
10+
)
11+
12+
/*
13+
Copyright (C) 2019 Ulbora Labs LLC. (www.ulboralabs.com)
14+
All rights reserved.
15+
16+
Copyright (C) 2019 Ken Williamson
17+
All rights reserved.
18+
19+
This program is free software: you can redistribute it and/or modify
20+
it under the terms of the GNU General Public License as published by
21+
the Free Software Foundation, either version 3 of the License, or
22+
(at your option) any later version.
23+
This program is distributed in the hope that it will be useful,
24+
but WITHOUT ANY WARRANTY; without even the implied warranty of
25+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26+
GNU General Public License for more details.
27+
You should have received a copy of the GNU General Public License
28+
along with this program. If not, see <http://www.gnu.org/licenses/>.
29+
30+
*/
31+
32+
//JwtCompress JwtCompress
33+
type JwtCompress struct {
34+
}
35+
36+
//CompressJwt CompressJwt
37+
func (c *JwtCompress) CompressJwt(jwt string) string {
38+
//compress jwt with zlib and package with base64
39+
var rtn string
40+
var b bytes.Buffer
41+
w, err := zlib.NewWriterLevel(&b, flate.BestCompression)
42+
if err == nil {
43+
w.Write([]byte(jwt))
44+
w.Close()
45+
rtn = base64.StdEncoding.EncodeToString(b.Bytes())
46+
}
47+
return rtn
48+
}
49+
50+
//UnCompressJwt UnCompressJwt
51+
func (c *JwtCompress) UnCompressJwt(cjwt string) string {
52+
//uncompress jwt with zlib after converting from base64
53+
var rtn string
54+
var b bytes.Buffer
55+
decoded, derr := base64.StdEncoding.DecodeString(cjwt)
56+
if derr == nil {
57+
b.Write(decoded)
58+
r, err := zlib.NewReader(&b)
59+
if err == nil {
60+
var out bytes.Buffer
61+
io.Copy(&out, r)
62+
r.Close()
63+
rtn = out.String()
64+
}
65+
}
66+
return rtn
67+
}

compresstoken/compressToken_test.go

+31
Large diffs are not rendered by default.

compresstoken/coverage.out

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mode: set
2+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:37.54,42.16 4 1
3+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:47.2,47.12 1 1
4+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:42.16,46.3 3 1
5+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:51.57,56.17 4 1
6+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:66.2,66.12 1 1
7+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:56.17,59.17 3 1
8+
github.com/Ulbora/GoAuth2/compresstoken/compressToken.go:59.17,64.4 4 1

handlers/clientRestHandlers.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func (h *OauthRestHandler) GetClientSearchList(w http.ResponseWriter, r *http.Re
240240
var getCltsURL = "/ulbora/rs/client/search"
241241

242242
var gcltscl oc.Claim
243-
gcltscl.Role = "admin"
243+
gcltscl.Role = "superAdmin"
244244
gcltscl.URL = getCltsURL
245245
gcltscl.Scope = "read"
246246
//fmt.Println("client: ", h.Client)

handlers/coverage.out

+163-155
Large diffs are not rendered by default.

handlers/oauthHandlers.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"log"
99
"net/http"
1010

11+
cp "github.com/Ulbora/GoAuth2/compresstoken"
1112
m "github.com/Ulbora/GoAuth2/managers"
1213
oa "github.com/Ulbora/GoAuth2/oauthclient"
1314
rc "github.com/Ulbora/GoAuth2/rolecontrol"
@@ -35,9 +36,11 @@ import (
3536

3637
//OauthRestHandler OauthRestHandler
3738
type OauthRestHandler struct {
38-
Manager m.Manager
39-
Client oa.Client
40-
AssetControl rc.AssetControl
39+
Manager m.Manager
40+
Client oa.Client
41+
AssetControl rc.AssetControl
42+
TokenCompressed bool
43+
JwtCompress cp.JwtCompress
4144
}
4245

4346
//GetNewRestHandler GetNewRestHandler

handlers/utilites.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import (
3838
*/
3939

4040
//UseWebHandler UseWebHandler
41-
func UseWebHandler(dbi db.Database) *OauthWebHandler {
41+
func UseWebHandler(dbi db.Database, compressJtw bool) *OauthWebHandler {
4242
var oauthManagerw m.OauthManager
4343
var oauthMySqldbw msdb.MySQLOauthDB
4444
oauthMySqldbw.DB = dbi
@@ -50,11 +50,12 @@ func UseWebHandler(dbi db.Database) *OauthWebHandler {
5050

5151
var wh OauthWebHandler
5252
wh.Manager = &oauthManagerw
53+
wh.TokenCompressed = compressJtw
5354
return &wh
5455
}
5556

5657
//UseRestHandler UseRestHandler
57-
func UseRestHandler(dbi db.Database, assets string) *OauthRestHandler {
58+
func UseRestHandler(dbi db.Database, assets string, compressJtw bool) *OauthRestHandler {
5859
var oauthManager m.OauthManager
5960
var oauthMySqldb msdb.MySQLOauthDB
6061
oauthMySqldb.DB = dbi
@@ -67,6 +68,7 @@ func UseRestHandler(dbi db.Database, assets string) *OauthRestHandler {
6768

6869
var clt oa.OauthClient
6970
clt.Manager = &oauthManager
71+
clt.TokenCompressed = compressJtw
7072
rh.Client = &clt
7173

7274
var curs []rc.ControlledURL
@@ -81,5 +83,6 @@ func UseRestHandler(dbi db.Database, assets string) *OauthRestHandler {
8183
var ac rc.OauthAssets
8284
ac.AddControledURLs(&curs)
8385
rh.AssetControl = &ac
86+
rh.TokenCompressed = compressJtw
8487
return &rh
8588
}

handlers/utilites_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
func TestUseHanders_UseWebHandler(t *testing.T) {
1111
var dbi db.Database
12-
h := UseWebHandler(dbi)
12+
h := UseWebHandler(dbi, false)
1313
if h == nil {
1414
t.Fail()
1515
}
@@ -18,7 +18,7 @@ func TestUseHanders_UseWebHandler(t *testing.T) {
1818
func TestUseHanders_UseRestHandler(t *testing.T) {
1919
var dbi db.Database
2020
var assets = "WwogICB7CiAgICAgICJ1cmwiOiIvdWxib3JhL3JzL2NsaWVudEFsbG93ZWRVcmkvYWRkIiwKICAgICAgImFzc2V0cyI6WwogICAgICAgICB7CiAgICAgICAgICAgICJjb250cm9sbGVkQXNzZXQiOiJ1bGJvcmEiLAogICAgICAgICAgICAiYWxsb3dlZFJvbGUiOiJzdXBlckFkbWluIgogICAgICAgICB9CiAgICAgIF0KICAgfSwKICAgewogICAgICAidXJsIjoiL3VsYm9yYS9ycy9jbGllbnRBbGxvd2VkVXJpL3VwZGF0ZSIsCiAgICAgICJhc3NldHMiOlsKICAgICAgICAgewogICAgICAgICAgICAiY29udHJvbGxlZEFzc2V0IjoidWxib3JhIiwKICAgICAgICAgICAgImFsbG93ZWRSb2xlIjoic3VwZXJBZG1pbiIKICAgICAgICAgfQogICAgICBdCiAgIH0sCiAgIHsKICAgICAgInVybCI6Ii91bGJvcmEvcnMvY2xpZW50Um9sZS9hZGQiLAogICAgICAiYXNzZXRzIjpbCiAgICAgICAgIHsKICAgICAgICAgICAgImNvbnRyb2xsZWRBc3NldCI6InN1cGVyQWRtaW4iLAogICAgICAgICAgICAiYWxsb3dlZFJvbGUiOiJzdXBlckFkbWluIgogICAgICAgICB9CiAgICAgIF0KICAgfQpd"
21-
h := UseRestHandler(dbi, assets)
21+
h := UseRestHandler(dbi, assets, false)
2222
if h == nil {
2323
t.Fail()
2424
}

handlers/validateTokenRestHandlers.go

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ type ValidationResponse struct {
3838
func (h *OauthRestHandler) ValidateAccessToken(w http.ResponseWriter, r *http.Request) {
3939
var vdtr m.ValidateAccessTokenReq
4040
vdtsuc, gerr := h.ProcessBody(r, &vdtr)
41+
if h.TokenCompressed {
42+
vdtr.AccessToken = h.JwtCompress.UnCompressJwt(vdtr.AccessToken)
43+
fmt.Println("uncompressed token in validate: ", vdtr.AccessToken)
44+
}
4145
fmt.Println("vdtsuc: ", vdtsuc)
4246
fmt.Println("vdtr: ", vdtr)
4347
fmt.Println("gerr: ", gerr)

handlers/validateTokenRestHandlers_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net/http/httptest"
1212
"testing"
1313

14+
cp "github.com/Ulbora/GoAuth2/compresstoken"
1415
m "github.com/Ulbora/GoAuth2/managers"
1516
)
1617

@@ -43,6 +44,39 @@ func TestOauthRestHandler_ValidateToken(t *testing.T) {
4344
}
4445
}
4546

47+
func TestOauthRestHandler_ValidateTokenCompressed(t *testing.T) {
48+
var oh OauthRestHandler
49+
50+
var man m.MockManager
51+
man.MockValidateAccessTokenSuccess = true
52+
oh.Manager = &man
53+
oh.TokenCompressed = true
54+
55+
h := oh.GetNewRestHandler()
56+
var token = "jdljdfldjslkjdsdfgdfgdffgdfgfdfgdfgdfgdfgdfdfdfdfdfdfdfdfgdgdfgdffgdfgdfdfgfdfgdfdfgddddgdgdgdgdgdgdgddggdgdgdgdggdfgdfgdfgdgflkldksldfks"
57+
var jc cp.JwtCompress
58+
tkn := jc.CompressJwt(token)
59+
fmt.Println("compressed token in test", tkn)
60+
fmt.Println("uncompressed token in test", jc.UnCompressJwt(tkn))
61+
62+
aJSON := ioutil.NopCloser(bytes.NewBufferString(`{"accessToken":"eNpUjFEKRDEIAy87JKD58/6w4NJHSwYcRVKkUKhJF4O87NDZ/rwx1+cedATAT/DnV6OVDj1BPb8AAAD//8ZtNs8=", "hashed": false, "userId":"someUser", "clientId": 2, "role": "someRole", "uri": "someUri", "scope":"someScope"}`))
63+
//aJSON, _ := json.Marshal(robj)
64+
//fmt.Println("aJSON: ", aJSON)
65+
r, _ := http.NewRequest("POST", "/ffllist", aJSON)
66+
//r, _ := http.NewRequest("POST", "/ffllist", nil)
67+
r.Header.Set("Content-Type", "application/json")
68+
w := httptest.NewRecorder()
69+
h.ValidateAccessToken(w, r)
70+
resp := w.Result()
71+
body, _ := ioutil.ReadAll(resp.Body)
72+
var bdy ValidationResponse
73+
json.Unmarshal(body, &bdy)
74+
fmt.Println("body: ", string(body))
75+
if w.Code != 200 || w.Header().Get("Content-Type") != "application/json" || !bdy.Valid {
76+
t.Fail()
77+
}
78+
}
79+
4680
func TestOauthRestHandler_ValidateTokenNotValid(t *testing.T) {
4781
var oh OauthRestHandler
4882

handlers/webAuthorizationHandlers.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (h *OauthWebHandler) Authorize(w http.ResponseWriter, r *http.Request) {
9393
ari.ClientID = clientIDAuth
9494
ari.RedirectURI = redirectURLAuth
9595
ari.Scope = scopeAuth
96-
ari.State = scopeAuth
96+
ari.State = stateAuth
9797

9898
if loggedInAuth == true && userAuth != nil {
9999
fmt.Println("loggedIn: ", loggedInAuth)
@@ -134,6 +134,9 @@ func (h *OauthWebHandler) Authorize(w http.ResponseWriter, r *http.Request) {
134134
if iauthed {
135135
isuc, im := h.Manager.AuthorizeImplicit(&aut)
136136
if isuc && im.Token != "" {
137+
if h.TokenCompressed {
138+
im.Token = h.JwtCompress.CompressJwt(im.Token)
139+
}
137140
http.Redirect(w, r, redirectURLAuth+"?token="+im.Token+"&token_type=bearer&state="+stateAuth, http.StatusFound)
138141
} else {
139142
http.Redirect(w, r, accessDeniedErrorURL, http.StatusFound)
@@ -269,6 +272,9 @@ func (h *OauthWebHandler) ApplicationAuthorizationByUser(w http.ResponseWriter,
269272
fmt.Println("aaiSuc", aaiSuc)
270273
fmt.Println("irtn", irtn)
271274
if aaiSuc && irtn.Token != "" {
275+
if h.TokenCompressed {
276+
irtn.Token = h.JwtCompress.CompressJwt(irtn.Token)
277+
}
272278
http.Redirect(w, r, aaari.RedirectURI+"?token="+irtn.Token+"&token_type=bearer&state="+aaari.State, http.StatusFound)
273279
} else {
274280
var aaipg PageParams

handlers/webAuthorizationHandlers_test.go

+76
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,38 @@ func TestOauthWebHandler_AuthorizeImplicit(t *testing.T) {
123123
}
124124
}
125125

126+
func TestOauthWebHandler_AuthorizeImplicitCompressed(t *testing.T) {
127+
var om m.MockManager
128+
om.MockImplicitAuthorized = true
129+
om.MockImplicitAuthorizeSuccess = true
130+
var impRtn m.ImplicitReturn
131+
impRtn.ID = 5
132+
impRtn.Token = "gjfldflkl"
133+
om.MockImplicitReturn = impRtn
134+
//om.MockAuthCode = 55
135+
//om.MockAuthCodeString = "rr666"
136+
137+
var wh OauthWebHandler
138+
wh.Manager = &om
139+
wh.TokenCompressed = true
140+
h := wh.GetNewWebHandler()
141+
r, _ := http.NewRequest("GET", "/test?response_type=token&client_id=125&redirect_uri=http://tester.com/test&scope=web&state=123", nil)
142+
//r.Header.Set("Content-Type", "application/json")
143+
w := httptest.NewRecorder()
144+
s, suc := wh.getSession(r)
145+
fmt.Println("suc: ", suc)
146+
s.Values["loggedIn"] = true
147+
s.Values["user"] = "tester"
148+
s.Save(r, w)
149+
h.Authorize(w, r)
150+
fmt.Println("code: ", w.Code)
151+
fmt.Println("location: ", w.HeaderMap["Location"])
152+
loc := w.HeaderMap["Location"]
153+
if w.Code != 302 || loc[0] != "http://tester.com/test?token=eNpKz0rLSUnLyc4BBAAA//8SXAOx&token_type=bearer&state=123" {
154+
t.Fail()
155+
}
156+
}
157+
126158
func TestOauthWebHandler_AuthorizeImplicitNotAuth(t *testing.T) {
127159
var om m.MockManager
128160
om.MockImplicitAuthorized = false
@@ -677,6 +709,50 @@ func TestOauthWebHandler_AuthorizeByUserToken(t *testing.T) {
677709
}
678710
}
679711

712+
func TestOauthWebHandler_AuthorizeByUserTokenCompressed(t *testing.T) {
713+
var om m.MockManager
714+
om.MockAuthCodeAuthorized = true
715+
om.MockAuthCodeAuthorizeSuccess = true
716+
om.MockImplicitAuthorizeSuccess = true
717+
var acc m.ImplicitReturn
718+
acc.ID = 55
719+
acc.Token = "lllkldskldfk"
720+
721+
om.MockImplicitReturn = acc
722+
om.MockAuthCode = 55
723+
om.MockAuthCodeString = "rr666"
724+
725+
var ari AuthorizeRequestInfo
726+
ari.ResponseType = "token"
727+
ari.ClientID = 1234
728+
ari.RedirectURI = "http://test.com/test"
729+
ari.Scope = "web"
730+
ari.State = "12eee"
731+
732+
var wh OauthWebHandler
733+
wh.Templates = template.Must(template.ParseFiles("testHtmls/test.html"))
734+
wh.Manager = &om
735+
wh.TokenCompressed = true
736+
h := wh.GetNewWebHandler()
737+
r, _ := http.NewRequest("GET", "/test?response_type=token&authorize=true", nil)
738+
//r.Header.Set("Content-Type", "application/json")
739+
w := httptest.NewRecorder()
740+
s, suc := wh.getSession(r)
741+
fmt.Println("suc: ", suc)
742+
s.Values["loggedIn"] = true
743+
s.Values["user"] = "tester"
744+
s.Values["authReqInfo"] = &ari
745+
746+
s.Save(r, w)
747+
h.ApplicationAuthorizationByUser(w, r)
748+
fmt.Println("code: ", w.Code)
749+
fmt.Println("location: ", w.HeaderMap["Location"])
750+
loc := w.HeaderMap["Location"]
751+
if w.Code != 302 || loc[0] != "http://test.com/test?token=eNrKycnJzkkpzs5JScsGBAAA//8gswT/&token_type=bearer&state=12eee" {
752+
t.Fail()
753+
}
754+
}
755+
680756
func TestOauthWebHandler_AuthorizeByUserTokenFailedAuth(t *testing.T) {
681757
var om m.MockManager
682758
om.MockAuthCodeAuthorized = true

handlers/webOauthHandlers.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"html/template"
88
"net/http"
99

10+
cp "github.com/Ulbora/GoAuth2/compresstoken"
1011
m "github.com/Ulbora/GoAuth2/managers"
1112
gs "github.com/Ulbora/go-sessions"
1213
"github.com/gorilla/sessions"
@@ -47,10 +48,12 @@ const (
4748

4849
//OauthWebHandler OauthWebHandler
4950
type OauthWebHandler struct {
50-
Manager m.Manager
51-
Session gs.GoSession
52-
Templates *template.Template
53-
Store *sessions.CookieStore
51+
Manager m.Manager
52+
Session gs.GoSession
53+
Templates *template.Template
54+
Store *sessions.CookieStore
55+
TokenCompressed bool
56+
JwtCompress cp.JwtCompress
5457
//SessInit bool
5558
}
5659

handlers/webTokenHandlers.go

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ func (h *OauthWebHandler) Token(w http.ResponseWriter, r *http.Request) {
126126
h.SetContentType(w)
127127
h.SetSecurityHeader(w)
128128
w.WriteHeader(http.StatusOK)
129+
if h.TokenCompressed {
130+
token.AccessToken = h.JwtCompress.CompressJwt(token.AccessToken)
131+
}
129132
resJSON, _ := json.Marshal(token)
130133
fmt.Fprint(w, string(resJSON))
131134
} else if caseDef {

0 commit comments

Comments
 (0)