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

mendersoftware / mender-server / 1978029483

11 Aug 2025 02:15PM UTC coverage: 65.755% (+0.3%) from 65.495%
1978029483

Pull #860

gitlab-ci

kjaskiewiczz
docs(useradm): move API specification to single file

Changelog: Title
Ticket: QA-1094
Signed-off-by: Krzysztof Jaskiewicz <krzysztof.jaskiewicz@northern.tech>
Pull Request #860: docs(useradm): move API specification to single file

29261 of 44500 relevant lines covered (65.76%)

1.44 hits per line

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

72.28
/backend/pkg/identity/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

15
package identity
16

17
import (
18
        "net/http"
19
        "regexp"
20

21
        "github.com/gin-gonic/gin"
22

23
        "github.com/mendersoftware/mender-server/pkg/log"
24
        urest "github.com/mendersoftware/mender-server/pkg/rest.utils"
25
)
26

27
type MiddlewareOptions struct {
28
        // PathRegex sets the regex for the path for which this middleware
29
        // applies. Defaults to "^/api/management/v[0-9.]{1,6}/.+".
30
        PathRegex *string
31

32
        // UpdateLogger adds the decoded identity to the log context.
33
        UpdateLogger *bool
34
}
35

36
func NewMiddlewareOptions() *MiddlewareOptions {
8✔
37
        return new(MiddlewareOptions)
8✔
38
}
8✔
39

40
func (opts *MiddlewareOptions) SetPathRegex(regex string) *MiddlewareOptions {
2✔
41
        opts.PathRegex = &regex
2✔
42
        return opts
2✔
43
}
2✔
44

45
func (opts *MiddlewareOptions) SetUpdateLogger(updateLogger bool) *MiddlewareOptions {
8✔
46
        opts.UpdateLogger = &updateLogger
8✔
47
        return opts
8✔
48
}
8✔
49

50
func middlewareWithLogger(c *gin.Context) {
8✔
51
        var (
8✔
52
                err    error
8✔
53
                jwt    string
8✔
54
                idty   Identity
8✔
55
                logCtx = log.Ctx{}
8✔
56
                key    = "sub"
8✔
57
                ctx    = c.Request.Context()
8✔
58
                l      = log.FromContext(ctx)
8✔
59
        )
8✔
60
        if FromContext(ctx) != nil {
8✔
61
                c.Next()
×
62
                return
×
63
        }
×
64
        jwt, err = ExtractJWTFromHeader(c.Request)
8✔
65
        if err != nil {
12✔
66
                goto exitUnauthorized
4✔
67
        }
68
        idty, err = ExtractIdentity(jwt)
8✔
69
        if err != nil {
10✔
70
                goto exitUnauthorized
2✔
71
        }
72
        ctx = WithContext(ctx, &idty)
8✔
73
        if idty.IsDevice {
13✔
74
                key = "device_id"
5✔
75
        } else if idty.IsUser {
20✔
76
                key = "user_id"
7✔
77
        }
7✔
78
        logCtx[key] = idty.Subject
8✔
79
        if idty.Tenant != "" {
13✔
80
                logCtx["tenant_id"] = idty.Tenant
5✔
81
        }
5✔
82
        if idty.Plan != "" {
11✔
83
                logCtx["plan"] = idty.Plan
3✔
84
        }
3✔
85
        ctx = log.WithContext(ctx, l.F(logCtx))
8✔
86

8✔
87
        c.Request = c.Request.WithContext(ctx)
8✔
88
        return
8✔
89
exitUnauthorized:
8✔
90
        c.Header("WWW-Authenticate", `Bearer realm="ManagementJWT"`)
4✔
91
        urest.RenderError(c, http.StatusUnauthorized, err)
4✔
92
        c.Abort()
4✔
93
}
94

95
func middlewareBase(c *gin.Context) {
×
96
        var (
×
97
                err  error
×
98
                jwt  string
×
99
                idty Identity
×
100
                ctx  = c.Request.Context()
×
101
        )
×
102
        jwt, err = ExtractJWTFromHeader(c.Request)
×
103
        if err != nil {
×
104
                goto exitUnauthorized
×
105
        }
106
        idty, err = ExtractIdentity(jwt)
×
107
        if err != nil {
×
108
                goto exitUnauthorized
×
109
        }
110
        ctx = WithContext(ctx, &idty)
×
111
        c.Request = c.Request.WithContext(ctx)
×
112
        return
×
113
exitUnauthorized:
×
114
        c.Header("WWW-Authenticate", `Bearer realm="ManagementJWT"`)
×
115
        urest.RenderError(c, http.StatusUnauthorized, err)
×
116
        c.Abort()
×
117
}
118

119
func Middleware(opts ...*MiddlewareOptions) gin.HandlerFunc {
8✔
120

8✔
121
        var middleware gin.HandlerFunc
8✔
122

8✔
123
        // Initialize default options
8✔
124
        opt := NewMiddlewareOptions().
8✔
125
                SetUpdateLogger(true)
8✔
126
        for _, o := range opts {
10✔
127
                if o == nil {
2✔
128
                        continue
×
129
                }
130
                if o.PathRegex != nil {
4✔
131
                        opt.PathRegex = o.PathRegex
2✔
132
                }
2✔
133
                if o.UpdateLogger != nil {
2✔
134
                        opt.UpdateLogger = o.UpdateLogger
×
135
                }
×
136
        }
137

138
        if *opt.UpdateLogger {
16✔
139
                middleware = middlewareWithLogger
8✔
140
        } else {
8✔
141
                middleware = middlewareBase
×
142
        }
×
143

144
        if opt.PathRegex != nil {
10✔
145
                pathRegex := regexp.MustCompile(*opt.PathRegex)
2✔
146
                return func(c *gin.Context) {
4✔
147
                        if !pathRegex.MatchString(c.FullPath()) {
4✔
148
                                return
2✔
149
                        }
2✔
150
                        middleware(c)
2✔
151
                }
152
        }
153
        return middleware
7✔
154
}
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