/
parser.go
110 lines (92 loc) · 3.05 KB
/
parser.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Tencent is pleased to support the open source community by making 蓝鲸 available.
* Copyright (C) 2017-2018 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package parser
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"regexp"
"strings"
"icenter/src/auth/meta"
"icenter/src/common"
"icenter/src/common/backbone"
"icenter/src/common/metadata"
"icenter/src/common/util"
"github.com/emicklei/go-restful"
)
func ParseAttribute(req *restful.Request, engine *backbone.Engine) (*meta.AuthAttribute, error) {
body, err := util.PeekRequest(req.Request)
if err != nil {
return nil, err
}
meta := struct {
Metadata metadata.Metadata `json:"metadata"`
}{}
// TODO: this condition should be optimized.
// one of the api like body is an array is
// put: /api/v3/objectatt/group/property
if len(body) > 0 && body[0] != '[' {
if err := json.Unmarshal(body, &meta); err != nil {
return nil, fmt.Errorf("parse attribute, but unmarshal body failed, err: %v", err)
}
}
elements, err := urlParse(req.Request.URL.Path)
if err != nil {
return nil, err
}
requestContext := &RequestContext{
Header: req.Request.Header,
Method: req.Request.Method,
URI: req.Request.URL.Path,
Elements: elements,
Body: body,
Metadata: meta.Metadata,
}
stream, err := newParseStream(requestContext, engine)
if err != nil {
return nil, err
}
return stream.Parse()
}
// ParseCommonInfo get common info from req, aims at avoiding too much repeat code
func ParseCommonInfo(requestHeader *http.Header) (*meta.CommonInfo, error) {
commonInfo := new(meta.CommonInfo)
userInfo, err := ParseUserInfo(requestHeader)
if err != nil {
return nil, err
}
commonInfo.User = *userInfo
return commonInfo, nil
}
func ParseUserInfo(requestHeader *http.Header) (*meta.UserInfo, error) {
userInfo := new(meta.UserInfo)
user := requestHeader.Get(common.BKHTTPHeaderUser)
if len(user) == 0 {
return nil, errors.New("parse user info failed, miss BK_User in your request header")
}
userInfo.UserName = user
supplierID := requestHeader.Get(common.BKHTTPOwnerID)
if len(supplierID) == 0 {
return nil, errors.New("parse user info failed, miss bk_supplier_id in your request header")
}
userInfo.SupplierAccount = supplierID
return userInfo, nil
}
// url example: /api/v3/create/model
var urlRegex = regexp.MustCompile(`^/api/([^/]+)(/[^/]+)+/?$`)
func urlParse(url string) (elements []string, err error) {
if !urlRegex.MatchString(url) {
return nil, fmt.Errorf("invalid url format, url=%s", url)
}
return strings.Split(url, "/")[1:], nil
}