• 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

0.0
/main.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
        "strings"
21

22
        "github.com/mendersoftware/go-lib-micro/config"
23
        "github.com/mendersoftware/go-lib-micro/log"
24
        "github.com/urfave/cli"
25

26
        . "github.com/mendersoftware/useradm/config"
27
        "github.com/mendersoftware/useradm/model"
28
        "github.com/mendersoftware/useradm/store/mongo"
29
)
30

31
func main() {
×
32
        if err := doMain(os.Args); err != nil {
×
33
                os.Exit(1)
×
34
        }
×
35
}
36

37
func doMain(args []string) error {
×
38
        var debug bool
×
39
        var configPath string
×
40

×
41
        app := cli.NewApp()
×
42
        app.Usage = "user administration service"
×
43
        app.Flags = []cli.Flag{
×
44
                cli.StringFlag{
×
45
                        Name: "config",
×
46
                        Usage: "Configuration `FILE`." +
×
47
                                " Supports JSON, TOML, YAML and HCL formatted configs.",
×
48
                        Destination: &configPath,
×
49
                },
×
50
                cli.BoolFlag{
×
51
                        Name:  "dev",
×
52
                        Usage: "Use development setup",
×
53
                },
×
54
                cli.BoolFlag{
×
55
                        Name:        "debug",
×
56
                        Usage:       "Enable debug logging",
×
57
                        Destination: &debug,
×
58
                },
×
59
        }
×
60
        app.Commands = []cli.Command{
×
61
                {
×
62
                        Name:  "server",
×
63
                        Usage: "Run the service as a server",
×
64
                        Flags: []cli.Flag{
×
65
                                cli.BoolFlag{
×
66
                                        Name:  "automigrate",
×
67
                                        Usage: "Run database migrations before starting.",
×
68
                                },
×
69
                        },
×
70

×
71
                        Action: runServer,
×
72
                },
×
73
                {
×
74
                        Name:  "create-user",
×
75
                        Usage: "Create user",
×
76
                        Flags: []cli.Flag{
×
77
                                cli.StringFlag{
×
78
                                        Name:  "username",
×
79
                                        Usage: "Name of created user, must be an email address",
×
80
                                },
×
81
                                cli.StringFlag{
×
82
                                        Name:  "password",
×
83
                                        Usage: "User's password, leave empty to have it read from stdin",
×
84
                                },
×
85
                                cli.StringFlag{
×
86
                                        Name:  "user-id",
×
87
                                        Usage: "User ID, if already generated/available (optional).",
×
88
                                },
×
89
                                cli.StringFlag{
×
90
                                        Name:  "tenant-id",
×
91
                                        Usage: "Tenant ID, if running a multitenant setup (optional).",
×
92
                                },
×
93
                        },
×
94
                        Action: runCreateUser,
×
95
                },
×
96
                {
×
97
                        Name:  "set-password",
×
98
                        Usage: "Set password",
×
99
                        Flags: []cli.Flag{
×
100
                                cli.StringFlag{
×
101
                                        Name:  "username",
×
102
                                        Usage: "Name of created user, must be an email address",
×
103
                                },
×
104
                                cli.StringFlag{
×
105
                                        Name:  "password",
×
106
                                        Usage: "User's password, leave empty to have it read from stdin",
×
107
                                },
×
108
                                cli.StringFlag{
×
109
                                        Name:  "tenant-id",
×
110
                                        Usage: "Tenant ID, if running a multitenant setup (optional).",
×
111
                                },
×
112
                        },
×
113
                        Action: runSetPassword,
×
114
                },
×
115
                {
×
116
                        Name:  "migrate",
×
117
                        Usage: "Run migrations",
×
118
                        Flags: []cli.Flag{
×
119
                                cli.StringFlag{
×
120
                                        Name:  "tenant",
×
121
                                        Usage: "Takes ID of specific tenant to migrate.",
×
122
                                },
×
123
                        },
×
124

×
125
                        Action: runMigrate,
×
126
                },
×
127
        }
×
128

×
129
        app.Action = runServer
×
130
        app.Before = func(args *cli.Context) error {
×
131
                log.Setup(debug)
×
132

×
133
                err := config.FromConfigFile(configPath, ConfigDefaults)
×
134
                if err != nil {
×
135
                        return cli.NewExitError(
×
136
                                fmt.Sprintf("error loading configuration: %s", err),
×
137
                                1)
×
138
                }
×
139

140
                // Enable setting conig values by environment variables
141
                config.Config.SetEnvPrefix("USERADM")
×
142
                config.Config.AutomaticEnv()
×
143

×
144
                if config.Config.IsSet(SettingPlanDefinitions) {
×
145
                        log.NewEmpty().Info(
×
146
                                "loading plan definitions from configuration",
×
147
                        )
×
148
                        err := model.LoadPlans(
×
149
                                config.Config.GetString(SettingPlanDefinitions),
×
150
                        )
×
151
                        if err != nil {
×
152
                                return fmt.Errorf(
×
153
                                        "failed to load Plans from config: %w",
×
154
                                        err,
×
155
                                )
×
156
                        }
×
157
                }
158

159
                return nil
×
160
        }
161
        err := app.Run(args)
×
162
        if err != nil {
×
163
                log.NewEmpty().Fatal(err)
×
164
        }
×
165
        return err
×
166
}
167

168
func runServer(args *cli.Context) error {
×
169
        devSetup := args.GlobalBool("dev")
×
170

×
171
        l := log.New(log.Ctx{})
×
172

×
173
        if devSetup {
×
174
                l.Infof("setting up development configuration")
×
175
                config.Config.Set(SettingMiddleware, EnvDev)
×
176
        }
×
177

178
        l.Print("User Administration Service starting up")
×
179

×
180
        ctx := context.Background()
×
181

×
182
        db, err := mongo.NewDataStoreMongo(dataStoreMongoConfigFromAppConfig(config.Config))
×
183
        if err != nil {
×
184
                return cli.NewExitError(
×
185
                        fmt.Sprintf("failed to connect to db: %v", err),
×
186
                        2)
×
187
        }
×
188

189
        if args.Bool("automigrate") {
×
190
                db = db.WithAutomigrate()
×
191
        }
×
192

193
        if config.Config.Get(SettingTenantAdmAddr) != "" {
×
194
                db = db.WithMultitenant()
×
195
        }
×
196
        err = db.Migrate(ctx, mongo.DbVersion)
×
197
        if err != nil {
×
198
                return cli.NewExitError(
×
199
                        fmt.Sprintf("failed to run migrations: %v", err),
×
200
                        3)
×
201
        }
×
202

203
        err = RunServer(config.Config)
×
204
        if err != nil {
×
205
                return cli.NewExitError(err.Error(), 4)
×
206
        }
×
207
        return nil
×
208
}
209

210
func runCreateUser(args *cli.Context) error {
×
211
        email := model.Email(strings.ToLower(args.String("username")))
×
212
        err := commandCreateUser(
×
213
                config.Config,
×
214
                email,
×
215
                args.String("password"),
×
216
                args.String("user-id"),
×
217
                args.String("tenant-id"),
×
218
        )
×
219
        if err != nil {
×
220
                return cli.NewExitError(err.Error(), 5)
×
221
        }
×
222
        return nil
×
223
}
224

225
func runMigrate(args *cli.Context) error {
×
226
        err := commandMigrate(config.Config, args.String("tenant"))
×
227
        if err != nil {
×
228
                return cli.NewExitError(err.Error(), 6)
×
229
        }
×
230
        return nil
×
231
}
232

233
func runSetPassword(args *cli.Context) error {
×
234
        email := model.Email(strings.ToLower(args.String("username")))
×
235
        err := commandSetPassword(
×
236
                config.Config, email,
×
237
                args.String("password"), args.String("tenant-id"),
×
238
        )
×
239
        if err != nil {
×
240
                return cli.NewExitError(err.Error(), 7)
×
241
        }
×
242
        return nil
×
243
}
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