Files
micromdm/cmd/mdmctl/apply_user.go

96 lines
2.3 KiB
Go

package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"github.com/micromdm/plist"
"github.com/pkg/errors"
"github.com/micromdm/micromdm/pkg/crypto/password"
"github.com/micromdm/micromdm/platform/user"
)
func (cmd *applyCommand) applyUser(args []string) error {
flagset := flag.NewFlagSet("users", flag.ExitOnError)
var (
flUserManifest = flagset.String("f", "", "Path to user manifest")
flTemplate = flagset.Bool("template", false, "Print a JSON example of a user manifest.")
flPassword = flagset.String("password", "", "Password of the user. Only required when creating a new user.")
)
flagset.Usage = usageFor(flagset, "mdmctl apply users [flags]")
if err := flagset.Parse(args); err != nil {
return err
}
if *flTemplate {
printUserTemplate()
return nil
}
manifestData, err := ioutil.ReadFile(*flUserManifest)
if err != nil {
return errors.Wrap(err, "read user manifest file")
}
var manifest user.User
if err := json.Unmarshal(manifestData, &manifest); err != nil {
return errors.Wrap(err, "unmarshal user manifest")
}
if manifest.UUID == "" && *flPassword == "" {
return errors.New("password argument must be provided when creating a user")
}
if *flPassword != "" {
salted, err := password.SaltedSHA512PBKDF2(*flPassword)
if err != nil {
return errors.Wrap(err, "salting plaintext password")
}
hashDict := struct {
SaltedSHA512PBKDF2 password.SaltedSHA512PBKDF2Dictionary `plist:"SALTED-SHA512-PBKDF2"`
}{
SaltedSHA512PBKDF2: salted,
}
hashPlist, err := plist.Marshal(hashDict)
if err != nil {
return errors.Wrap(err, "marshal salted password to plist")
}
manifest.PasswordHash = hashPlist
}
usr, err := cmd.usersvc.ApplyUser(context.TODO(), manifest)
if err != nil {
return errors.Wrap(err, "apply user with mdmctl")
}
f, err := os.OpenFile(*flUserManifest, os.O_RDWR, os.ModeAppend)
if err != nil {
return errors.Wrapf(err, "open user manifest %s", *flUserManifest)
}
defer f.Close()
enc := json.NewEncoder(f)
enc.SetIndent("", " ")
if err := enc.Encode(usr); err != nil {
return errors.Wrap(err, "encode user manifest")
}
return nil
}
func printUserTemplate() {
jsn := `
{
"user_shortname": "",
"user_longname": "",
"hidden": false
}
`
fmt.Println(jsn)
}