Skip to content

Commit d879250

Browse files
committed
完善auther接口
1 parent 8fbd967 commit d879250

File tree

8 files changed

+98
-28
lines changed

8 files changed

+98
-28
lines changed

http/mock/auth.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ var (
1515

1616
// NewMockAuther mock
1717
func NewMockAuther() router.Auther {
18+
1819
return &mockAuther{}
1920
}
2021

2122
type mockAuther struct{}
2223

23-
func (m *mockAuther) Auth(h http.Header) (authInfo interface{}, err error) {
24+
func (m *mockAuther) Auth(h http.Header, entry router.Entry) (authInfo interface{}, err error) {
2425
authHeader := h.Get("Authorization")
2526
if authHeader == "" {
2627
return nil, exception.NewUnauthorized("Authorization missed in header")

http/router/auther.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package router
33
import "net/http"
44

55
// Auther 设置受保护路由使用的认证器
6+
// Header 用于鉴定身份
7+
// Entry 用于鉴定权限
68
type Auther interface {
7-
Auth(http.Header) (authInfo interface{}, err error)
9+
Auth(http.Header, Entry) (authInfo interface{}, err error)
810
}
911

1012
// The AutherFunc type is an adapter to allow the use of

http/router/entry.go

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,67 @@
11
package router
22

3+
import "fmt"
4+
35
// Entry 路由条目
46
type Entry struct {
5-
Name string `json:"name,omitempty"`
6-
Resource string `json:"resource,omitempty"`
77
Path string `json:"path,omitempty"`
88
Method string `json:"method,omitempty"`
9+
Resource string `json:"resource,omitempty"`
910
Protected bool `json:"protected"`
1011
Labels map[string]string `json:"labels,omitempty"`
1112
}
1213

14+
func gernateEntryID(path, mothod string) string {
15+
return path + "." + mothod
16+
}
17+
18+
// ID entry 唯一标识符
19+
func (e *Entry) ID() string {
20+
return e.Path + "." + e.Method
21+
}
22+
1323
// NewEntrySet 实例化一个集合
1424
func NewEntrySet() *EntrySet {
15-
return &EntrySet{}
25+
return &EntrySet{
26+
items: make(map[string]*Entry),
27+
}
1628
}
1729

1830
// EntrySet 路由集合
1931
type EntrySet struct {
20-
items []Entry
32+
items map[string]*Entry
2133
}
2234

2335
// AddEntry 添加理由条目
24-
func (s *EntrySet) AddEntry(e ...Entry) {
25-
s.items = append(s.items, e...)
36+
func (s *EntrySet) AddEntry(es ...*Entry) error {
37+
for _, e := range es {
38+
if v, ok := s.items[e.ID()]; ok {
39+
return fmt.Errorf("router entry %s has exist", v.ID())
40+
}
41+
s.items[e.ID()] = e
42+
}
43+
44+
return nil
2645
}
2746

2847
// ShowEntries 显示理由条目
2948
func (s *EntrySet) ShowEntries() []Entry {
30-
return s.items
49+
entries := make([]Entry, 0, len(s.items))
50+
for _, v := range s.items {
51+
entries = append(entries, *v)
52+
}
53+
54+
return entries
55+
}
56+
57+
// FindEntry 通过函数地址找到对于的路由条目
58+
// 由于该接口是高频接口, 为了不影响性能 采用指针输出, 请不要修改Entry
59+
func (s *EntrySet) FindEntry(path, method string) *Entry {
60+
id := gernateEntryID(path, method)
61+
entry, ok := s.items[id]
62+
if !ok {
63+
return nil
64+
}
65+
66+
return entry
3167
}

http/router/entry_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package router_test
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/infraboard/mcube/http/response"
7+
)
8+
9+
func indexHandler(w http.ResponseWriter, r *http.Request) {
10+
response.Success(w, "ok")
11+
return
12+
}

http/router/httprouter/httprouter.go

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package httprouter
33
import (
44
"log"
55
"net/http"
6+
"strings"
67

78
"github.com/infraboard/mcube/http/context"
89
"github.com/infraboard/mcube/http/response"
@@ -24,15 +25,18 @@ type httpRouter struct {
2425
l logger.Logger
2526

2627
middlewareChain []router.Middleware
27-
entries []*entry
28+
entrySet *router.EntrySet
2829
auther router.Auther
2930
mergedHandler http.Handler
3031
labels []*router.Label
32+
notFound http.Handler
3133
}
3234

3335
// New 基于社区的httprouter进行封装
3436
func New() router.Router {
3537
r := &httpRouter{
38+
notFound: http.HandlerFunc(http.NotFound),
39+
entrySet: router.NewEntrySet(),
3640
r: &httprouter.Router{
3741
RedirectTrailingSlash: true,
3842
RedirectFixedPath: true,
@@ -55,7 +59,6 @@ func (r *httpRouter) Use(m router.Middleware) {
5559
func (r *httpRouter) AddProtected(method, path string, h http.HandlerFunc) {
5660
e := &entry{
5761
Entry: router.Entry{
58-
Name: router.GetHandlerFuncName(h),
5962
Method: method,
6063
Path: path,
6164
Protected: true,
@@ -69,7 +72,6 @@ func (r *httpRouter) AddProtected(method, path string, h http.HandlerFunc) {
6972
func (r *httpRouter) AddPublict(method, path string, h http.HandlerFunc) {
7073
e := &entry{
7174
Entry: router.Entry{
72-
Name: router.GetHandlerFuncName(h),
7375
Method: method,
7476
Path: path,
7577
Protected: false,
@@ -104,21 +106,15 @@ func (r *httpRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
104106
}
105107

106108
func (r *httpRouter) GetEndpoints() *router.EntrySet {
107-
es := router.NewEntrySet()
108-
109-
for i := range r.entries {
110-
es.AddEntry(r.entries[i].Entry)
111-
}
112-
113-
return es
109+
return r.entrySet
114110
}
115111

116112
func (r *httpRouter) EnableAPIRoot() {
117113
r.AddPublict("GET", "/", r.apiRoot)
118114
}
119115

120116
func (r *httpRouter) apiRoot(w http.ResponseWriter, req *http.Request) {
121-
response.Success(w, r.entries)
117+
response.Success(w, r.entrySet.ShowEntries)
122118
return
123119
}
124120

@@ -151,9 +147,14 @@ func (r *httpRouter) add(e *entry) {
151147
func (r *httpRouter) addHandler(protected bool, method, path string, h http.Handler) {
152148
r.r.Handle(method, path,
153149
func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
150+
entry := r.findEntry(method, path)
151+
if entry == nil {
152+
r.notFound.ServeHTTP(w, req)
153+
return
154+
}
154155
// 使用auther进行认证
155156
if protected && r.auther != nil {
156-
authInfo, err := r.auther.Auth(req.Header)
157+
authInfo, err := r.auther.Auth(req.Header, *entry)
157158
if err != nil {
158159
response.Failed(w, err)
159160
return
@@ -184,5 +185,23 @@ func (r *httpRouter) addEntry(e *entry) {
184185
kv := r.labels[i]
185186
e.Labels[kv.Key()] = kv.Value()
186187
}
187-
r.entries = append(r.entries, e)
188+
189+
if err := r.entrySet.AddEntry(&e.Entry); err != nil {
190+
panic(err)
191+
}
192+
}
193+
194+
func (r *httpRouter) findEntry(method, path string) *router.Entry {
195+
hander, paras, _ := r.r.Lookup(method, path)
196+
if hander == nil {
197+
return nil
198+
}
199+
200+
targetPath := path
201+
for _, kv := range paras {
202+
targetPath = strings.Replace(targetPath, ":"+kv.Key, kv.Value, 1)
203+
}
204+
205+
return r.entrySet.FindEntry(targetPath, method)
206+
188207
}

http/router/httprouter/httprouter_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"testing"
77

88
"github.com/infraboard/mcube/exception"
9-
"github.com/infraboard/mcube/http/mock"
109
"github.com/infraboard/mcube/http/context"
10+
"github.com/infraboard/mcube/http/mock"
1111
"github.com/infraboard/mcube/http/response"
1212
"github.com/infraboard/mcube/http/router"
1313
"github.com/infraboard/mcube/http/router/httprouter"

http/router/httprouter/subrouter.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ func (r *subRouter) With(m ...router.Middleware) router.SubRouter {
4242
func (r *subRouter) AddProtected(method, path string, h http.HandlerFunc) {
4343
e := &entry{
4444
Entry: router.Entry{
45-
Name: router.GetHandlerFuncName(h),
46-
Method: method,
47-
Path: path,
48-
Labels: map[string]string{},
45+
Resource: r.resourceName,
46+
Method: method,
47+
Path: path,
48+
Labels: map[string]string{},
4949
},
5050
needAuth: true,
5151
h: h,
@@ -58,7 +58,6 @@ func (r *subRouter) AddPublict(method, path string, h http.HandlerFunc) {
5858
e := &entry{
5959
Entry: router.Entry{
6060
Resource: r.resourceName,
61-
Name: router.GetHandlerFuncName(h),
6261
Method: method,
6362
Path: path,
6463
Labels: map[string]string{},

http/router/httprouter/subrouter_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func (a *subRouterTestSuit) testResourceRouterOK() func(t *testing.T) {
7575
req, _ := http.NewRequest("GET", "/v1/resources/", nil)
7676
a.root.ServeHTTP(w, req)
7777

78+
t.Log(a.root.GetEndpoints().ShowEntries())
7879
a.should.Equal(w.Code, 200)
7980
}
8081
}

0 commit comments

Comments
 (0)