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

mendersoftware / useradm / 1830670534

08 May 2025 10:54AM UTC coverage: 59.747% (-27.3%) from 87.019%
1830670534

push

gitlab-ci

alfrunes
Merge `alfrunes:1.22.x` into `mendersoftware:1.22.x`

2363 of 3955 relevant lines covered (59.75%)

12.76 hits per line

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

15.15
/commands.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 main
15

16
import (
17
        "context"
18
        "fmt"
19
        "os"
20

21
        "github.com/mendersoftware/go-lib-micro/config"
22
        "github.com/mendersoftware/go-lib-micro/identity"
23
        "github.com/mendersoftware/go-lib-micro/log"
24
        "github.com/pkg/errors"
25
        "golang.org/x/term"
26

27
        "github.com/mendersoftware/useradm/client/tenant"
28
        . "github.com/mendersoftware/useradm/config"
29
        "github.com/mendersoftware/useradm/model"
30
        "github.com/mendersoftware/useradm/store/mongo"
31
        useradm "github.com/mendersoftware/useradm/user"
32
)
33

34
// safeReadPassword reads a user password from a terminal in a safe way (without
35
// echoing the characters input by the user)
36
func safeReadPassword() (string, error) {
×
37
        stdinfd := int(os.Stdin.Fd())
×
38

×
39
        if !term.IsTerminal(stdinfd) {
×
40
                return "", errors.New("stdin is not a terminal")
×
41
        }
×
42

43
        fmt.Fprintf(os.Stderr, "Enter password: ")
×
44
        raw, err := term.ReadPassword(int(os.Stdin.Fd()))
×
45
        if err != nil {
×
46
                return "", errors.Wrap(err, "failed to read password")
×
47
        }
×
48
        fmt.Fprintf(os.Stderr, "\n")
×
49

×
50
        return string(raw), nil
×
51
}
52

53
func commandCreateUser(
54
        c config.Reader,
55
        username model.Email,
56
        password, userId, tenantId string,
57
) error {
2✔
58
        ctx := context.Background()
2✔
59
        l := log.NewEmpty()
2✔
60

2✔
61
        l.Debugf("create user '%s'", username)
2✔
62

2✔
63
        if password == "" {
2✔
64
                var err error
×
65
                if password, err = safeReadPassword(); err != nil {
×
66
                        return err
×
67
                }
×
68
        }
69

70
        u := model.User{
2✔
71
                Email:    username,
2✔
72
                Password: password,
2✔
73
        }
2✔
74

2✔
75
        if userId != "" {
2✔
76
                u.ID = userId
×
77
        }
×
78

79
        if err := u.Validate(); err != nil {
3✔
80
                return errors.Wrap(err, "user validation failed")
1✔
81
        }
1✔
82

83
        db, err := mongo.GetDataStoreMongo(dataStoreMongoConfigFromAppConfig(c))
1✔
84
        if err != nil {
2✔
85
                return errors.Wrap(err, "database connection failed")
1✔
86
        }
1✔
87

88
        ua := useradm.NewUserAdm(nil, db, useradm.Config{})
×
89
        if tadmAddr := c.GetString(SettingTenantAdmAddr); tadmAddr != "" {
×
90
                l.Infof("setting up tenant verification")
×
91

×
92
                tc := tenant.NewClient(tenant.Config{
×
93
                        TenantAdmAddr: tadmAddr,
×
94
                })
×
95

×
96
                ua = ua.WithTenantVerification(tc)
×
97
                ctx = identity.WithContext(ctx, &identity.Identity{
×
98
                        Tenant: tenantId,
×
99
                })
×
100
        }
×
101

102
        if err := ua.CreateUser(ctx, &u); err != nil {
×
103
                return errors.Wrap(err, "creating user failed")
×
104
        }
×
105

106
        fmt.Printf("%s\n", u.ID)
×
107

×
108
        return nil
×
109
}
110

111
func getTenantContext(tenantId string) context.Context {
×
112
        ctx := context.Background()
×
113
        if tenantId != "" {
×
114
                id := &identity.Identity{
×
115
                        Tenant: tenantId,
×
116
                }
×
117

×
118
                ctx = identity.WithContext(ctx, id)
×
119
        }
×
120

121
        return ctx
×
122
}
123

124
func commandMigrate(c config.Reader, tenantId string) error {
×
125
        l := log.New(log.Ctx{})
×
126

×
127
        l.Printf("User Administration Service starting up")
×
128

×
129
        if tenantId != "" {
×
130
                l.Printf("migrating tenant %v", tenantId)
×
131
        } else {
×
132
                l.Printf("migrating all the tenants")
×
133
        }
×
134

135
        db, err := mongo.NewDataStoreMongo(dataStoreMongoConfigFromAppConfig(c))
×
136

×
137
        if err != nil {
×
138
                return errors.Wrap(err, "database connection failed")
×
139
        }
×
140

141
        // we want to apply migrations
142
        db = db.WithAutomigrate()
×
143

×
144
        ctx := context.Background()
×
145

×
146
        if tenantId != "" {
×
147
                err = db.MigrateTenant(ctx, mongo.DbVersion, tenantId)
×
148
        } else {
×
149
                err = db.Migrate(ctx, mongo.DbVersion)
×
150
        }
×
151
        if err != nil {
×
152
                return errors.Wrap(err, "failed to run migrations")
×
153
        }
×
154

155
        return nil
×
156

157
}
158

159
func commandSetPassword(
160
        c config.Reader,
161
        username model.Email,
162
        password, tenantId string,
163
) error {
×
164
        l := log.NewEmpty()
×
165

×
166
        l.Debugf("set password for '%s'", username)
×
167

×
168
        if password == "" {
×
169
                var err error
×
170
                if password, err = safeReadPassword(); err != nil {
×
171
                        return err
×
172
                }
×
173
        }
174

175
        db, err := mongo.GetDataStoreMongo(dataStoreMongoConfigFromAppConfig(c))
×
176
        if err != nil {
×
177
                return errors.Wrap(err, "database connection failed")
×
178
        }
×
179

180
        ua := useradm.NewUserAdm(nil, db, useradm.Config{})
×
181

×
182
        u := model.User{
×
183
                Email:    username,
×
184
                Password: password,
×
185
        }
×
186

×
187
        if err := u.Validate(); err != nil {
×
188
                return errors.Wrap(err, "user validation failed")
×
189
        }
×
190

191
        ctx := getTenantContext(tenantId)
×
192

×
193
        uu := model.UserUpdate{
×
194
                Email:    username,
×
195
                Password: password,
×
196
        }
×
197

×
198
        if err := ua.SetPassword(ctx, uu); err != nil {
×
199
                return errors.Wrap(err, "setting password failed")
×
200
        }
×
201

202
        return nil
×
203
}
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