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

mendersoftware / useradm / 1030325529

09 Oct 2023 11:24AM UTC coverage: 89.205% (-0.3%) from 89.534%
1030325529

Pull #383

gitlab-ci

tranchitella
feat: support for Ed25519 server keys for signing the JWT tokens

Ticket: MEN-5676
Changelog: Title

Signed-off-by: Fabio Tranchitella <fabio.tranchitella@northern.tech>
Pull Request #383: feat: support for Ed25519 server keys for signing the JWT tokens

97 of 118 new or added lines in 7 files covered. (82.2%)

2 existing lines in 1 file now uncovered.

2661 of 2983 relevant lines covered (89.21%)

118.85 hits per line

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

73.49
/server.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 main
15

16
import (
17
        "net/http"
18

19
        "github.com/ant0ine/go-json-rest/rest"
20
        "github.com/mendersoftware/go-lib-micro/config"
21
        "github.com/mendersoftware/go-lib-micro/log"
22
        "github.com/pkg/errors"
23

24
        api_http "github.com/mendersoftware/useradm/api/http"
25
        "github.com/mendersoftware/useradm/authz"
26
        "github.com/mendersoftware/useradm/client/tenant"
27
        . "github.com/mendersoftware/useradm/config"
28
        "github.com/mendersoftware/useradm/jwt"
29
        "github.com/mendersoftware/useradm/keys"
30
        "github.com/mendersoftware/useradm/store/mongo"
31
        useradm "github.com/mendersoftware/useradm/user"
32
)
33

34
func SetupAPI(stacktype string, authz authz.Authorizer, jwth jwt.Handler,
35
        jwthFallback jwt.Handler) (*rest.Api, error) {
4✔
36
        api := rest.NewApi()
4✔
37
        if err := SetupMiddleware(api, stacktype, authz, jwth, jwthFallback); err != nil {
5✔
38
                return nil, errors.Wrap(err, "failed to setup middleware")
1✔
39
        }
1✔
40

41
        //this will override the framework's error resp to the desired one:
42
        // {"error": "msg"}
43
        // instead of:
44
        // {"Error": "msg"}
45
        rest.ErrorFieldName = "error"
3✔
46

3✔
47
        return api, nil
3✔
48
}
49

50
func getJWTHandler(privateKeyType, privateKeyPath string) (jwt.Handler, error) {
2✔
51
        if privateKeyType == SettingServerPrivKeyTypeRSA {
4✔
52
                privKey, err := keys.LoadRSAPrivate(privateKeyPath)
2✔
53
                if err != nil {
2✔
NEW
54
                        return nil, errors.Wrap(err, "failed to read rsa private key")
×
NEW
55
                }
×
56
                return jwt.NewJWTHandlerRS256(privKey), nil
2✔
NEW
57
        } else if privateKeyType == SettingServerPrivKeyTypeEd25519 {
×
NEW
58
                privKey, err := keys.LoadEd25519Private(privateKeyPath)
×
NEW
59
                if err != nil {
×
NEW
60
                        return nil, errors.Wrap(err, "failed to read ed25519 private key")
×
NEW
61
                }
×
NEW
62
                return jwt.NewJWTHandlerEd25519(privKey), nil
×
63
        }
NEW
64
        return nil, errors.Errorf("unsupported server private key type %v", privateKeyType)
×
65
}
66

67
func RunServer(c config.Reader) error {
2✔
68

2✔
69
        l := log.New(log.Ctx{})
2✔
70

2✔
71
        authz := &SimpleAuthz{}
2✔
72
        jwtHandler, err := getJWTHandler(
2✔
73
                c.GetString(SettingServerPrivKeyType),
2✔
74
                c.GetString(SettingServerPrivKeyPath),
2✔
75
        )
2✔
76
        var jwtFallbackHandler jwt.Handler
2✔
77
        fallback := c.GetString(SettingServerFallbackPrivKeyPath)
2✔
78
        if err == nil && fallback != "" {
2✔
NEW
79
                jwtFallbackHandler, err = getJWTHandler(
×
NEW
80
                        c.GetString(SettingServerFallbackPrivKeyType),
×
NEW
81
                        fallback,
×
NEW
82
                )
×
UNCOV
83
        }
×
84
        if err != nil {
2✔
NEW
85
                return err
×
UNCOV
86
        }
×
87

88
        db, err := mongo.GetDataStoreMongo(dataStoreMongoConfigFromAppConfig(c))
2✔
89
        if err != nil {
2✔
90
                return errors.Wrap(err, "database connection failed")
×
91
        }
×
92

93
        ua := useradm.NewUserAdm(jwtHandler, db,
2✔
94
                useradm.Config{
2✔
95
                        Issuer:                         c.GetString(SettingJWTIssuer),
2✔
96
                        ExpirationTimeSeconds:          int64(c.GetInt(SettingJWTExpirationTimeout)),
2✔
97
                        LimitSessionsPerUser:           c.GetInt(SettingLimitSessionsPerUser),
2✔
98
                        LimitTokensPerUser:             c.GetInt(SettingLimitTokensPerUser),
2✔
99
                        TokenLastUsedUpdateFreqMinutes: c.GetInt(SettingTokenLastUsedUpdateFreqMinutes),
2✔
100
                })
2✔
101

2✔
102
        if tadmAddr := c.GetString(SettingTenantAdmAddr); tadmAddr != "" {
3✔
103
                l.Infof("settting up tenant verification")
1✔
104

1✔
105
                tc := tenant.NewClient(tenant.Config{
1✔
106
                        TenantAdmAddr: tadmAddr,
1✔
107
                })
1✔
108

1✔
109
                ua = ua.WithTenantVerification(tc)
1✔
110
        }
1✔
111

112
        useradmapi := api_http.NewUserAdmApiHandlers(ua, db, jwtHandler,
2✔
113
                api_http.Config{
2✔
114
                        TokenMaxExpSeconds: c.GetInt(SettingTokenMaxExpirationSeconds),
2✔
115
                })
2✔
116

2✔
117
        api, err := SetupAPI(c.GetString(SettingMiddleware), authz, jwtHandler, jwtFallbackHandler)
2✔
118
        if err != nil {
2✔
119
                return errors.Wrap(err, "API setup failed")
×
120
        }
×
121

122
        apph, err := useradmapi.GetApp()
2✔
123
        if err != nil {
2✔
124
                return errors.Wrap(err, "useradm API handlers setup failed")
×
125
        }
×
126
        api.SetApp(apph)
2✔
127

2✔
128
        addr := c.GetString(SettingListen)
2✔
129
        l.Printf("listening on %s", addr)
2✔
130

2✔
131
        return http.ListenAndServe(addr, api.MakeHandler())
2✔
132
}
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