3
3
// webframework.
4
4
//
5
5
// Example:
6
- // package main
7
- // import (
8
- // "flag"
9
- // "time"
10
- // "github.com/gin-gonic/gin"
11
- // "github.com/golang/glog"
12
- // "github.com/szuecs/gin-glog"
13
- // "github.com/zalando/gin-oauth2"
14
- // "golang.org/x/oauth2"
15
- // )
16
6
//
17
- // var OAuth2Endpoint = oauth2.Endpoint{
18
- // AuthURL: "https://token.oauth2.corp.com/access_token",
19
- // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
20
- // }
7
+ // package main
8
+ // import (
9
+ // "flag"
10
+ // "time"
11
+ // "github.com/gin-gonic/gin"
12
+ // "github.com/golang/glog"
13
+ // "github.com/szuecs/gin-glog"
14
+ // "github.com/zalando/gin-oauth2"
15
+ // "golang.org/x/oauth2"
16
+ // )
21
17
//
22
- // func UidCheck(tc *TokenContainer, ctx *gin.Context) bool {
23
- // uid := tc.Scopes["uid"].(string)
24
- // if uid != "sszuecs" {
25
- // return false
26
- // }
27
- // ctx.Set("uid", uid)
28
- // return true
29
- // }
18
+ // var OAuth2Endpoint = oauth2.Endpoint{
19
+ // AuthURL: "https://token.oauth2.corp.com/access_token",
20
+ // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
21
+ // }
30
22
//
31
- // func main() {
32
- // flag.Parse()
33
- // router := gin.New()
34
- // router.Use(ginglog.Logger(3 * time.Second))
35
- // router.Use(gin.Recovery())
23
+ // func UidCheck(tc *TokenContainer, ctx *gin.Context) bool {
24
+ // uid := tc.Scopes["uid"].(string)
25
+ // if uid != "sszuecs" {
26
+ // return false
27
+ // }
28
+ // ctx.Set("uid", uid)
29
+ // return true
30
+ // }
36
31
//
37
- // ginoauth2.VarianceTimer = 300 * time.Millisecond // defaults to 30s
32
+ // func main() {
33
+ // flag.Parse()
34
+ // router := gin.New()
35
+ // router.Use(ginglog.Logger(3 * time.Second))
36
+ // router.Use(gin.Recovery())
38
37
//
39
- // public := router.Group("/api")
40
- // public.GET("/", func(c *gin.Context) {
41
- // c.JSON(200, gin.H{"message": "Hello to public world"})
42
- // })
38
+ // ginoauth2.VarianceTimer = 300 * time.Millisecond // defaults to 30s
43
39
//
44
- // private := router.Group("/api/private")
45
- // private.Use(ginoauth2.Auth(UidCheck, OAuth2Endpoint))
46
- // private.GET("/", func(c *gin.Context) {
47
- // c.JSON(200, gin.H{"message": "Hello from private"})
48
- // })
40
+ // public := router.Group("/api")
41
+ // public.GET("/", func(c *gin.Context) {
42
+ // c.JSON(200, gin.H{"message": "Hello to public world"})
43
+ // })
49
44
//
50
- // glog.Info("bootstrapped application")
51
- // router.Run(":8081")
45
+ // private := router.Group("/api/private")
46
+ // private.Use(ginoauth2.Auth(UidCheck, OAuth2Endpoint))
47
+ // private.GET("/", func(c *gin.Context) {
48
+ // c.JSON(200, gin.H{"message": "Hello from private"})
49
+ // })
52
50
//
51
+ // glog.Info("bootstrapped application")
52
+ // router.Run(":8081")
53
53
package ginoauth2
54
54
55
55
import (
@@ -125,12 +125,12 @@ func infofv2(f string, args ...interface{}) {
125
125
func extractToken (r * http.Request ) (* oauth2.Token , error ) {
126
126
hdr := r .Header .Get ("Authorization" )
127
127
if hdr == "" {
128
- return nil , errors .New ("No authorization header" )
128
+ return nil , errors .New ("no authorization header" )
129
129
}
130
130
131
131
th := strings .Split (hdr , " " )
132
132
if len (th ) != 2 {
133
- return nil , errors .New ("Incomplete authorization header" )
133
+ return nil , errors .New ("incomplete authorization header" )
134
134
}
135
135
136
136
return & oauth2.Token {AccessToken : th [1 ], TokenType : th [0 ]}, nil
@@ -179,10 +179,10 @@ func ParseTokenContainer(t *oauth2.Token, data map[string]interface{}) (*TokenCo
179
179
exp := data ["expires_in" ].(float64 )
180
180
tok := data ["access_token" ].(string )
181
181
if ttype != t .TokenType {
182
- return nil , errors .New ("Token type mismatch" )
182
+ return nil , errors .New ("token type mismatch" )
183
183
}
184
184
if tok != t .AccessToken {
185
- return nil , errors .New ("Mismatch between verify request and answer" )
185
+ return nil , errors .New ("mismatch between verify request and answer" )
186
186
}
187
187
188
188
scopes := data ["scope" ].([]interface {})
@@ -219,9 +219,11 @@ func getTokenContainerForToken(o Options, token *oauth2.Token) (*TokenContainer,
219
219
errorf ("[Gin-OAuth] JSON.Unmarshal failed caused by: %s" , err )
220
220
return nil , err
221
221
}
222
- if _ , ok := data ["error_description" ]; ok {
223
- var s string
224
- s = data ["error_description" ].(string )
222
+ if si , ok := data ["error_description" ]; ok {
223
+ s , ok := si .(string )
224
+ if ! ok {
225
+ s = ""
226
+ }
225
227
errorf ("[Gin-OAuth] RequestAuthInfo returned an error: %s" , s )
226
228
return nil , errors .New (s )
227
229
}
@@ -254,32 +256,30 @@ func getTokenContainer(o Options, ctx *gin.Context) (*TokenContainer, bool) {
254
256
return tc , true
255
257
}
256
258
257
- //
258
- // TokenContainer
259
- //
260
- // Validates that the AccessToken within TokenContainer is not expired and not empty.
259
+ // Valid validates that the AccessToken within TokenContainer is not
260
+ // expired and not empty.
261
261
func (t * TokenContainer ) Valid () bool {
262
262
if t .Token == nil {
263
263
return false
264
264
}
265
265
return t .Token .Valid ()
266
266
}
267
267
268
- // Router middleware that can be used to get an authenticated and authorized service for the whole router group.
268
+ // Auth implements a router middleware that can be used to get an
269
+ // authenticated and authorized service for the whole router group.
269
270
// Example:
270
271
//
271
- // var endpoints oauth2.Endpoint = oauth2.Endpoint{
272
- // AuthURL: "https://token.oauth2.corp.com/access_token",
273
- // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
274
- // }
275
- // var acl []ginoauth2.AccessTuple = []ginoauth2.AccessTuple{{"employee", 1070, "sszuecs"}, {"employee", 1114, "njuettner"}}
276
- // router := gin.Default()
277
- // private := router.Group("")
278
- // private.Use(ginoauth2.Auth(ginoauth2.UidCheck, ginoauth2.endpoints))
279
- // private.GET("/api/private", func(c *gin.Context) {
280
- // c.JSON(200, gin.H{"message": "Hello from private"})
281
- // })
282
- //
272
+ // var endpoints oauth2.Endpoint = oauth2.Endpoint{
273
+ // AuthURL: "https://token.oauth2.corp.com/access_token",
274
+ // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
275
+ // }
276
+ // var acl []ginoauth2.AccessTuple = []ginoauth2.AccessTuple{{"employee", 1070, "sszuecs"}, {"employee", 1114, "njuettner"}}
277
+ // router := gin.Default()
278
+ // private := router.Group("")
279
+ // private.Use(ginoauth2.Auth(ginoauth2.UidCheck, ginoauth2.endpoints))
280
+ // private.GET("/api/private", func(c *gin.Context) {
281
+ // c.JSON(200, gin.H{"message": "Hello from private"})
282
+ // })
283
283
func Auth (accessCheckFunction AccessCheckFunction , endpoints oauth2.Endpoint ) gin.HandlerFunc {
284
284
return AuthChain (endpoints , accessCheckFunction )
285
285
}
@@ -289,22 +289,21 @@ func Auth(accessCheckFunction AccessCheckFunction, endpoints oauth2.Endpoint) gi
289
289
// takes a chain of AccessCheckFunctions and only fails if all of them fails.
290
290
// Example:
291
291
//
292
- // var endpoints oauth2.Endpoint = oauth2.Endpoint{
293
- // AuthURL: "https://token.oauth2.corp.com/access_token",
294
- // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
295
- // }
296
- // var acl []ginoauth2.AccessTuple = []ginoauth2.AccessTuple{{"employee", 1070, "sszuecs"}, {"employee", 1114, "njuettner"}}
297
- // router := gin.Default()
298
- // private := router.Group("")
299
- // checkChain := []AccessCheckFunction{
300
- // ginoauth2.UidCheck,
301
- // ginoauth2.GroupCheck,
302
- // }
303
- // private.Use(ginoauth2.AuthChain(checkChain, ginoauth2.endpoints))
304
- // private.GET("/api/private", func(c *gin.Context) {
305
- // c.JSON(200, gin.H{"message": "Hello from private"})
306
- // })
307
- //
292
+ // var endpoints oauth2.Endpoint = oauth2.Endpoint{
293
+ // AuthURL: "https://token.oauth2.corp.com/access_token",
294
+ // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
295
+ // }
296
+ // var acl []ginoauth2.AccessTuple = []ginoauth2.AccessTuple{{"employee", 1070, "sszuecs"}, {"employee", 1114, "njuettner"}}
297
+ // router := gin.Default()
298
+ // private := router.Group("")
299
+ // checkChain := []AccessCheckFunction{
300
+ // ginoauth2.UidCheck,
301
+ // ginoauth2.GroupCheck,
302
+ // }
303
+ // private.Use(ginoauth2.AuthChain(checkChain, ginoauth2.endpoints))
304
+ // private.GET("/api/private", func(c *gin.Context) {
305
+ // c.JSON(200, gin.H{"message": "Hello from private"})
306
+ // })
308
307
func AuthChain (endpoint oauth2.Endpoint , accessCheckFunctions ... AccessCheckFunction ) gin.HandlerFunc {
309
308
return AuthChainOptions (Options {Endpoint : endpoint }, accessCheckFunctions ... )
310
309
}
@@ -322,15 +321,15 @@ func AuthChainOptions(o Options, accessCheckFunctions ...AccessCheckFunction) gi
322
321
if ! ok {
323
322
// set LOCATION header to auth endpoint such that the user can easily get a new access-token
324
323
ctx .Writer .Header ().Set ("Location" , o .Endpoint .AuthURL )
325
- ctx .AbortWithError (http .StatusUnauthorized , errors .New ("No token in context" ))
324
+ ctx .AbortWithError (http .StatusUnauthorized , errors .New ("no token in context" ))
326
325
varianceControl <- false
327
326
return
328
327
}
329
328
330
329
if ! tokenContainer .Valid () {
331
330
// set LOCATION header to auth endpoint such that the user can easily get a new access-token
332
331
ctx .Writer .Header ().Set ("Location" , o .Endpoint .AuthURL )
333
- ctx .AbortWithError (http .StatusUnauthorized , errors .New ("Invalid Token" ))
332
+ ctx .AbortWithError (http .StatusUnauthorized , errors .New ("invalid Token" ))
334
333
varianceControl <- false
335
334
return
336
335
}
@@ -342,7 +341,7 @@ func AuthChainOptions(o Options, accessCheckFunctions ...AccessCheckFunction) gi
342
341
}
343
342
344
343
if len (accessCheckFunctions )- 1 == i {
345
- ctx .AbortWithError (http .StatusForbidden , errors .New ("Access to the Resource is forbidden" ))
344
+ ctx .AbortWithError (http .StatusForbidden , errors .New ("access to the Resource is forbidden" ))
346
345
varianceControl <- false
347
346
return
348
347
}
@@ -356,7 +355,7 @@ func AuthChainOptions(o Options, accessCheckFunctions ...AccessCheckFunction) gi
356
355
return
357
356
}
358
357
case <- time .After (VarianceTimer ):
359
- ctx .AbortWithError (http .StatusGatewayTimeout , errors .New ("Authorization check overtime" ))
358
+ ctx .AbortWithError (http .StatusGatewayTimeout , errors .New ("authorization check overtime" ))
360
359
infofv2 ("[Gin-OAuth] %12v %s overtime" , time .Since (t ), ctx .Request .URL .Path )
361
360
return
362
361
}
@@ -375,22 +374,20 @@ func AuthChainOptions(o Options, accessCheckFunctions ...AccessCheckFunction) gi
375
374
//
376
375
// Example:
377
376
//
378
- // var endpoints oauth2.Endpoint = oauth2.Endpoint{
379
- // AuthURL: "https://token.oauth2.corp.com/access_token",
380
- // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
381
- // }
382
- // var acl []ginoauth2.AccessTuple = []ginoauth2.AccessTuple{{"employee", 1070, "sszuecs"}, {"employee", 1114, "njuettner"}}
383
- // router := gin.Default()
384
- // router.Use(ginoauth2.RequestLogger([]string{"uid"}, "data"))
385
- //
377
+ // var endpoints oauth2.Endpoint = oauth2.Endpoint{
378
+ // AuthURL: "https://token.oauth2.corp.com/access_token",
379
+ // TokenURL: "https://oauth2.corp.com/corp/oauth2/tokeninfo",
380
+ // }
381
+ // var acl []ginoauth2.AccessTuple = []ginoauth2.AccessTuple{{"employee", 1070, "sszuecs"}, {"employee", 1114, "njuettner"}}
382
+ // router := gin.Default()
383
+ // router.Use(ginoauth2.RequestLogger([]string{"uid"}, "data"))
386
384
func RequestLogger (keys []string , contentKey string ) gin.HandlerFunc {
387
385
return func (c * gin.Context ) {
388
386
request := c .Request
389
387
c .Next ()
390
388
err := c .Errors
391
389
if request .Method != "GET" && err == nil {
392
- data , e := c .Get (contentKey )
393
- if e != false { //key is non existent
390
+ if data , ok := c .Get (contentKey ); ! ok {
394
391
values := make ([]string , 0 )
395
392
for _ , key := range keys {
396
393
val , keyPresent := c .Get (key )
0 commit comments