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

mendersoftware / useradm / 800583681

pending completion
800583681

Pull #354

gitlab-ci

Fabio Tranchitella
feat: add support for never expiring PATs
Pull Request #354: feat: add support for never expiring PATs

66 of 71 new or added lines in 6 files covered. (92.96%)

117 existing lines in 5 files now uncovered.

2571 of 2875 relevant lines covered (89.43%)

127.6 hits per line

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

93.02
/jwt/jwt.go
1
// Copyright 2022 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 jwt
15

16
import (
17
        "crypto/rsa"
18

19
        jwtgo "github.com/golang-jwt/jwt/v4"
20
        "github.com/pkg/errors"
21
)
22

23
var (
24
        ErrTokenExpired = errors.New("jwt: token expired")
25
        ErrTokenInvalid = errors.New("jwt: token invalid")
26
)
27

28
// JWTHandler jwt generator/verifier
29
//go:generate ../utils/mockgen.sh
30
type Handler interface {
31
        ToJWT(t *Token) (string, error)
32
        // FromJWT parses the token and does basic validity checks (Claims.Valid().
33
        // returns:
34
        // ErrTokenExpired when the token is valid but expired
35
        // ErrTokenInvalid when the token is invalid (malformed, missing required claims, etc.)
36
        FromJWT(string) (*Token, error)
37
}
38

39
// JWTHandlerRS256 is an RS256-specific JWTHandler
40
type JWTHandlerRS256 struct {
41
        privKey         *rsa.PrivateKey
42
        fallbackPrivKey *rsa.PrivateKey
43
}
44

45
func NewJWTHandlerRS256(privKey *rsa.PrivateKey, fallbackPrivKey *rsa.PrivateKey) *JWTHandlerRS256 {
18✔
46
        return &JWTHandlerRS256{
18✔
47
                privKey:         privKey,
18✔
48
                fallbackPrivKey: fallbackPrivKey,
18✔
49
        }
18✔
50
}
18✔
51

52
func (j *JWTHandlerRS256) ToJWT(token *Token) (string, error) {
172✔
53
        //generate
172✔
54
        jt := jwtgo.NewWithClaims(jwtgo.SigningMethodRS256, &token.Claims)
172✔
55

172✔
56
        //sign
172✔
57
        data, err := jt.SignedString(j.privKey)
172✔
58
        return data, err
172✔
59
}
172✔
60

61
func (j *JWTHandlerRS256) FromJWT(tokstr string) (*Token, error) {
161✔
62
        var err error
161✔
63
        var jwttoken *jwtgo.Token
161✔
64
        for _, privKey := range []*rsa.PrivateKey{
161✔
65
                j.privKey,
161✔
66
                j.fallbackPrivKey,
161✔
67
        } {
334✔
68
                if privKey != nil {
336✔
69
                        jwttoken, err = jwtgo.ParseWithClaims(tokstr, &Claims{},
163✔
70
                                func(token *jwtgo.Token) (interface{}, error) {
321✔
71
                                        if _, ok := token.Method.(*jwtgo.SigningMethodRSA); !ok {
158✔
UNCOV
72
                                                return nil, errors.New("unexpected signing method: " + token.Method.Alg())
×
73
                                        }
×
74
                                        return &privKey.PublicKey, nil
158✔
75
                                },
76
                        )
77
                        if jwttoken != nil && err == nil {
314✔
78
                                break
151✔
79
                        }
80
                }
81
        }
82

83
        // our Claims return Mender-specific validation errors
84
        // go-jwt will wrap them in a generic ValidationError - unwrap and return directly
85
        if err != nil {
171✔
86
                err, ok := err.(*jwtgo.ValidationError)
10✔
87
                if ok && err.Inner != nil {
16✔
88
                        return nil, err.Inner
6✔
89
                }
6✔
90
                return nil, err
4✔
91
        }
92

93
        token := Token{}
151✔
94

151✔
95
        if claims, ok := jwttoken.Claims.(*Claims); ok && jwttoken.Valid {
302✔
96
                token.Claims = *claims
151✔
97
                return &token, nil
151✔
98
        }
151✔
UNCOV
99
        return nil, ErrTokenInvalid
×
100
}
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