• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / useradm / 1320952658

08 Dec 2023 03:39PM UTC coverage: 87.019%. Remained the same
1320952658

push

gitlab-ci

web-flow
Merge pull request #401 from mendersoftware/dependabot/go_modules/go.mongodb.org/mongo-driver-1.13.1

chore: bump go.mongodb.org/mongo-driver from 1.12.1 to 1.13.1

2869 of 3297 relevant lines covered (87.02%)

130.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.11
/authz/middleware.go
1
// Copyright 2023 Northern.tech AS
2
//
3
//        Licensed under the Apache License, Version 2.0 (the "License");
4
//        you may not use this file except in compliance with the License.
5
//        You may obtain a copy of the License at
6
//
7
//            http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//        Unless required by applicable law or agreed to in writing, software
10
//        distributed under the License is distributed on an "AS IS" BASIS,
11
//        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//        See the License for the specific language governing permissions and
13
//        limitations under the License.
14
package authz
15

16
import (
17
        "net/http"
18
        "strings"
19

20
        "github.com/ant0ine/go-json-rest/rest"
21
        "github.com/mendersoftware/go-lib-micro/log"
22
        "github.com/mendersoftware/go-lib-micro/rest_utils"
23

24
        "github.com/mendersoftware/useradm/jwt"
25
)
26

27
const (
28
        // token's key in request.Env
29
        ReqToken = "authz_token"
30
)
31

32
// AuthzMiddleware checks the authorization on a given request.
33
// It retrieves the token + requested resource and action, and delegates the authz check to an
34
// Authorizer.
35
type AuthzMiddleware struct {
36
        Authz              Authorizer
37
        ResFunc            ResourceActionExtractor
38
        JWTHandlers        map[int]jwt.Handler
39
        JWTFallbackHandler jwt.Handler
40
}
41

42
// Action combines info about the requested resourd + http method.
43
type Action struct {
44
        Resource string
45
        Method   string
46
}
47

48
// ResourceActionExtractor extracts Actions from requests.
49
type ResourceActionExtractor func(r *rest.Request) (*Action, error)
50

51
// MiddlewareFunc makes AuthzMiddleware implement the Middleware interface.
52
func (mw *AuthzMiddleware) MiddlewareFunc(h rest.HandlerFunc) rest.HandlerFunc {
11✔
53
        return func(w rest.ResponseWriter, r *rest.Request) {
145✔
54
                l := log.FromContext(r.Context())
134✔
55

134✔
56
                //get token, no token header = http 401
134✔
57
                tokstr, err := ExtractToken(r.Request)
134✔
58
                if err != nil {
137✔
59
                        rest_utils.RestErrWithLog(w, r, l, err, http.StatusUnauthorized)
3✔
60
                        return
3✔
61
                }
3✔
62

63
                keyId := jwt.GetKeyId(tokstr)
131✔
64

131✔
65
                if _, ok := mw.JWTHandlers[keyId]; !ok {
131✔
66
                        // we have not found the corresponding handler for the key by id
×
67
                        // on purpose we do not return common.ErrKeyIdNotFound -- to not allow
×
68
                        // the enumeration attack
×
69
                        rest_utils.RestErrWithLog(w, r, l, ErrAuthzTokenInvalid, http.StatusUnauthorized)
×
70
                        return
×
71
                }
×
72

73
                // parse token, insert into env
74
                token, err := mw.JWTHandlers[keyId].FromJWT(tokstr)
131✔
75
                if err != nil && mw.JWTFallbackHandler != nil {
131✔
76
                        token, err = mw.JWTFallbackHandler.FromJWT(tokstr)
×
77
                }
×
78
                if err != nil {
139✔
79
                        rest_utils.RestErrWithLog(w, r, l, ErrAuthzTokenInvalid, http.StatusUnauthorized)
8✔
80
                        return
8✔
81
                }
8✔
82

83
                r.Env[ReqToken] = token
123✔
84

123✔
85
                // extract resource action
123✔
86
                action, err := mw.ResFunc(r)
123✔
87
                if err != nil {
125✔
88
                        rest_utils.RestErrWithLogInternal(w, r, l, err)
2✔
89
                        return
2✔
90
                }
2✔
91

92
                ctx := r.Context()
121✔
93

121✔
94
                //authorize, no authz = http 403
121✔
95
                err = mw.Authz.Authorize(ctx, token, action.Resource, action.Method)
121✔
96
                if err != nil {
124✔
97
                        if err == ErrAuthzUnauthorized {
4✔
98
                                rest_utils.RestErrWithLog(w, r, l,
1✔
99
                                        ErrAuthzUnauthorized, http.StatusForbidden)
1✔
100
                        } else if err == ErrAuthzTokenInvalid {
4✔
101
                                rest_utils.RestErrWithLog(w, r, l,
1✔
102
                                        ErrAuthzTokenInvalid, http.StatusUnauthorized)
1✔
103
                        } else {
2✔
104
                                rest_utils.RestErrWithLogInternal(w, r, l, err)
1✔
105
                        }
1✔
106
                        return
3✔
107
                }
108

109
                h(w, r)
118✔
110
        }
111
}
112

113
// extracts JWT from authorization header
114
func ExtractToken(req *http.Request) (string, error) {
159✔
115
        const authHeaderName = "Authorization"
159✔
116
        auth := req.Header.Get(authHeaderName)
159✔
117
        if auth != "" {
316✔
118
                auths := strings.Fields(auth)
157✔
119
                if !strings.EqualFold(auths[0], "Bearer") || len(auths) < 2 {
159✔
120
                        return "", ErrInvalidAuthHeader
2✔
121
                }
2✔
122
                return auths[1], nil
155✔
123
        }
124
        cookie, err := req.Cookie("JWT")
2✔
125
        if err != nil {
3✔
126
                return "", ErrAuthzNoAuth
1✔
127
        }
1✔
128
        auth = cookie.Value
1✔
129
        if auth == "" {
1✔
130
                return "", ErrAuthzNoAuth
×
131
        }
×
132
        return auth, nil
1✔
133
}
134

135
func GetRequestToken(env map[string]interface{}) *jwt.Token {
117✔
136
        return env[ReqToken].(*jwt.Token)
117✔
137
}
117✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc