generated from clevergo/pkg-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
authz.go
62 lines (54 loc) · 1.5 KB
/
authz.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Copyright 2020 CleverGo. All rights reserved.
// Use of this source code is governed by a MIT style license that can be found
// in the LICENSE file.
package authz
import (
"errors"
"net/http"
"clevergo.tech/clevergo"
"github.com/casbin/casbin/v2"
)
// Errors
var (
ErrUnauthorized = clevergo.NewError(http.StatusUnauthorized, errors.New(http.StatusText(http.StatusUnauthorized)))
ErrForbidden = clevergo.NewError(http.StatusForbidden, errors.New("you are not allowed to access this page"))
)
// UserFunc is a function that returns a string which represents the authenticated user.
type UserFunc func(c *clevergo.Context) (id string, err error)
// New returns a middleware with the given enforcer, user function and optional options.
func New(enforcer *casbin.Enforcer, userFunc UserFunc, opts ...Option) clevergo.MiddlewareFunc {
a := &authorization{
enforcer: enforcer,
userFunc: userFunc,
}
for _, opt := range opts {
opt(a)
}
return a.Middleware
}
type authorization struct {
enforcer *casbin.Enforcer
userFunc UserFunc
skipper clevergo.Skipper
}
func (a *authorization) Middleware(next clevergo.Handle) clevergo.Handle {
return func(c *clevergo.Context) error {
if a.skipper == nil || !a.skipper(c) {
id, err := a.userFunc(c)
if err != nil {
return err
}
if id == "" {
return ErrUnauthorized
}
ok, err := a.enforcer.Enforce(id, c.Request.URL.Path, c.Request.Method)
if err != nil {
return err
}
if !ok {
return ErrForbidden
}
}
return next(c)
}
}