Skip to content

Commit

Permalink
blueprint: convert UserCustomization to types.Option
Browse files Browse the repository at this point in the history
  • Loading branch information
mvo5 committed Aug 15, 2024
1 parent ddb721c commit 23e0f8b
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 82 deletions.
28 changes: 14 additions & 14 deletions pkg/blueprint/customizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ type SSHKeyCustomization struct {
}

type UserCustomization struct {
Name string `json:"name" toml:"name"`
Description *string `json:"description,omitempty" toml:"description,omitempty"`
Password *string `json:"password,omitempty" toml:"password,omitempty"`
Key *string `json:"key,omitempty" toml:"key,omitempty"`
Home *string `json:"home,omitempty" toml:"home,omitempty"`
Shell *string `json:"shell,omitempty" toml:"shell,omitempty"`
Groups []string `json:"groups,omitempty" toml:"groups,omitempty"`
UID *int `json:"uid,omitempty" toml:"uid,omitempty"`
GID *int `json:"gid,omitempty" toml:"gid,omitempty"`
ExpireDate *int `json:"expiredate,omitempty" toml:"expiredate,omitempty"`
ForcePasswordReset *bool `json:"force_password_reset,omitempty" toml:"force_password_reset,omitempty"`
Name string `json:"name" toml:"name"`
Description types.Option[string] `json:"description,omitempty" toml:"description,omitempty"`
Password types.Option[string] `json:"password,omitempty" toml:"password,omitempty"`
Key types.Option[string] `json:"key,omitempty" toml:"key,omitempty"`
Home types.Option[string] `json:"home,omitempty" toml:"home,omitempty"`
Shell types.Option[string] `json:"shell,omitempty" toml:"shell,omitempty"`
Groups []string `json:"groups,omitempty" toml:"groups,omitempty"`
UID types.Option[int] `json:"uid,omitempty" toml:"uid,omitempty"`
GID types.Option[int] `json:"gid,omitempty" toml:"gid,omitempty"`
ExpireDate types.Option[int] `json:"expiredate,omitempty" toml:"expiredate,omitempty"`
ForcePasswordReset types.Option[bool] `json:"force_password_reset,omitempty" toml:"force_password_reset,omitempty"`
}

type GroupCustomization struct {
Expand Down Expand Up @@ -241,7 +241,7 @@ func (c *Customizations) GetUsers() []UserCustomization {
keyc := c.SSHKey[idx]
users = append(users, UserCustomization{
Name: keyc.User,
Key: &keyc.Key,
Key: types.Some(keyc.Key),
})
}
}
Expand All @@ -253,8 +253,8 @@ func (c *Customizations) GetUsers() []UserCustomization {
for idx := range users {
u := users[idx]
if u.Home != nil {
homedir := strings.TrimRight(*u.Home, "/")
u.Home = &homedir
homedir := strings.TrimRight(u.Home.Unwrap(), "/")
u.Home = types.Some(homedir)
users[idx] = u
}
}
Expand Down
34 changes: 17 additions & 17 deletions pkg/blueprint/customizations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ func TestCheckAllowed(t *testing.T) {
expectedUsers := []UserCustomization{
{
Name: "John",
Description: &Desc,
Password: &Pass,
Key: &Key,
Home: &Home,
Shell: &Shell,
Description: types.Some(Desc),
Password: types.Some(Pass),
Key: types.Some(Key),
Home: types.Some(Home),
Shell: types.Some(Shell),
Groups: Groups,
UID: &UID,
GID: &GID,
UID: types.Some(UID),
GID: types.Some(GID),
},
}

Expand Down Expand Up @@ -90,7 +90,7 @@ func TestSSHKey(t *testing.T) {
}

retUser := TestCustomizations.GetUsers()[0].Name
retKey := *TestCustomizations.GetUsers()[0].Key
retKey := TestCustomizations.GetUsers()[0].Key.Unwrap()

assert.Equal(t, expectedSSHKeys[0].User, retUser)
assert.Equal(t, expectedSSHKeys[0].Key, retKey)
Expand All @@ -113,16 +113,16 @@ func TestGetUsers(t *testing.T) {
expectedUsers := []UserCustomization{
{
Name: "John",
Description: &Desc,
Password: &Pass,
Key: &Key,
Home: &Home,
Shell: &Shell,
Description: types.Some(Desc),
Password: types.Some(Pass),
Key: types.Some(Key),
Home: types.Some(Home),
Shell: types.Some(Shell),
Groups: Groups,
UID: &UID,
GID: &GID,
ExpireDate: &ExpireDate,
ForcePasswordReset: &ForcePasswordReset,
UID: types.Some(UID),
GID: types.Some(GID),
ExpireDate: types.Some(ExpireDate),
ForcePasswordReset: types.Some(ForcePasswordReset),
},
}

Expand Down
23 changes: 13 additions & 10 deletions pkg/customizations/users/users.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package users

import "github.com/osbuild/images/pkg/blueprint"
import (
"github.com/osbuild/images/internal/types"
"github.com/osbuild/images/pkg/blueprint"
)

type User struct {
Name string
Description *string
Password *string
Key *string
Home *string
Shell *string
Description types.Option[string]
Password types.Option[string]
Key types.Option[string]
Home types.Option[string]
Shell types.Option[string]
Groups []string
UID *int
GID *int
ExpireDate *int
ForcePasswordReset *bool
UID types.Option[int]
GID types.Option[int]
ExpireDate types.Option[int]
ForcePasswordReset types.Option[bool]
}

type Group struct {
Expand Down
16 changes: 9 additions & 7 deletions pkg/manifest/anaconda_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"os"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/types"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
Expand Down Expand Up @@ -202,7 +202,9 @@ func (p *AnacondaInstaller) serializeEnd() {

func installerRootUser() osbuild.UsersStageOptionsUser {
return osbuild.UsersStageOptionsUser{
Password: common.ToPtr(""),
// lock root accont by default
// XXX: this could just be "Password: nil"
Password: types.Some(""),
}
}

Expand Down Expand Up @@ -252,11 +254,11 @@ func (p *AnacondaInstaller) payloadStages() []*osbuild.Stage {
installShell := "/usr/libexec/anaconda/run-anaconda"
installPassword := ""
installUser := osbuild.UsersStageOptionsUser{
UID: &installUID,
GID: &installGID,
Home: &installHome,
Shell: &installShell,
Password: &installPassword,
UID: types.Some(installUID),
GID: types.Some(installGID),
Home: types.Some(installHome),
Shell: types.Some(installShell),
Password: types.Some(installPassword),
}

usersStageOptions := &osbuild.UsersStageOptions{
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ func usersFirstBootOptions(users []users.User) *osbuild.FirstBootStageOptions {
sshdir := filepath.Join(home, ".ssh")

cmds = append(cmds, fmt.Sprintf("mkdir -p %s", sshdir))
cmds = append(cmds, fmt.Sprintf("sh -c 'echo %q >> %q'", *user.Key, filepath.Join(sshdir, "authorized_keys")))
cmds = append(cmds, fmt.Sprintf("sh -c 'echo %q >> %q'", user.Key.Unwrap(), filepath.Join(sshdir, "authorized_keys")))
cmds = append(cmds, fmt.Sprintf("chown %s:%s -Rc %s", user.Name, user.Name, sshdir))
}
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/manifest/ostree_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/types"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/users"
Expand Down Expand Up @@ -405,7 +406,8 @@ func (p *OSTreeDeployment) serialize() osbuild.Pipeline {
userOptions := &osbuild.UsersStageOptions{
Users: map[string]osbuild.UsersStageOptionsUser{
"root": {
Password: common.ToPtr("!locked"), // this is treated as crypted and locks/disables the password
// XXX: using "" or nil here is used in other places
Password: types.Some("!locked"), // this is treated as crypted and locks/disables the password
},
},
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/manifest/raw_bootc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/testdisk"
"github.com/osbuild/images/internal/types"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/manifest"
Expand Down Expand Up @@ -58,7 +59,7 @@ func TestRawBootcImageSerialize(t *testing.T) {

rawBootcPipeline := manifest.NewRawBootcImage(build, containers, pf)
rawBootcPipeline.PartitionTable = testdisk.MakeFakePartitionTable("/", "/boot", "/boot/efi")
rawBootcPipeline.Users = []users.User{{Name: "root", Key: common.ToPtr("some-ssh-key")}}
rawBootcPipeline.Users = []users.User{{Name: "root", Key: types.Some("some-ssh-key")}}
rawBootcPipeline.KernelOptionsAppend = []string{"karg1", "karg2"}

rawBootcPipeline.SerializeStart(nil, []container.Spec{{Source: "foo"}}, nil, nil)
Expand Down
29 changes: 15 additions & 14 deletions pkg/osbuild/users_stage.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package osbuild

import (
"github.com/osbuild/images/internal/types"
"github.com/osbuild/images/pkg/crypt"
"github.com/osbuild/images/pkg/customizations/users"
)
Expand All @@ -12,16 +13,16 @@ type UsersStageOptions struct {
func (UsersStageOptions) isStageOptions() {}

type UsersStageOptionsUser struct {
UID *int `json:"uid,omitempty"`
GID *int `json:"gid,omitempty"`
Groups []string `json:"groups,omitempty"`
Description *string `json:"description,omitempty"`
Home *string `json:"home,omitempty"`
Shell *string `json:"shell,omitempty"`
Password *string `json:"password,omitempty"`
Key *string `json:"key,omitempty"`
ExpireDate *int `json:"expiredate,omitempty"`
ForcePasswordReset *bool `json:"force_password_reset,omitempty"`
UID types.Option[int] `json:"uid,omitempty"`
GID types.Option[int] `json:"gid,omitempty"`
Groups []string `json:"groups,omitempty"`
Description types.Option[string] `json:"description,omitempty"`
Home types.Option[string] `json:"home,omitempty"`
Shell types.Option[string] `json:"shell,omitempty"`
Password types.Option[string] `json:"password,omitempty"`
Key types.Option[string] `json:"key,omitempty"`
ExpireDate types.Option[int] `json:"expiredate,omitempty"`
ForcePasswordReset types.Option[bool] `json:"force_password_reset,omitempty"`
}

func NewUsersStage(options *UsersStageOptions) *Stage {
Expand All @@ -39,18 +40,18 @@ func NewUsersStageOptions(userCustomizations []users.User, omitKey bool) (*Users
users := make(map[string]UsersStageOptionsUser, len(userCustomizations))
for _, uc := range userCustomizations {
// Don't hash empty passwords, set to nil to lock account
if uc.Password != nil && len(*uc.Password) == 0 {
if len(uc.Password.Unwrap()) == 0 {
uc.Password = nil
}

// Hash non-empty un-hashed passwords
if uc.Password != nil && !crypt.PasswordIsCrypted(*uc.Password) {
cryptedPassword, err := crypt.CryptSHA512(*uc.Password)
if uc.Password != nil && !crypt.PasswordIsCrypted(uc.Password.Unwrap()) {
cryptedPassword, err := crypt.CryptSHA512(uc.Password.Unwrap())
if err != nil {
return nil, err
}

uc.Password = &cryptedPassword
uc.Password = types.Some(cryptedPassword)
}

user := UsersStageOptionsUser{
Expand Down
34 changes: 17 additions & 17 deletions pkg/osbuild/users_stage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/types"
"github.com/osbuild/images/pkg/customizations/users"
)

Expand All @@ -28,15 +28,15 @@ func TestNewUsersStageOptionsPassword(t *testing.T) {
users := []users.User{
{
Name: "bart",
Password: &Pass,
Password: types.Some(Pass),
},
{
Name: "lisa",
Password: &CryptPass,
Password: types.Some(CryptPass),
},
{
Name: "maggie",
Password: &EmptyPass,
Password: types.Some(EmptyPass),
},
{
Name: "homer",
Expand All @@ -48,10 +48,10 @@ func TestNewUsersStageOptionsPassword(t *testing.T) {
require.NotNil(t, options)

// bart's password should now be a hash
assert.True(t, strings.HasPrefix(*options.Users["bart"].Password, "$6$"))
assert.True(t, strings.HasPrefix(options.Users["bart"].Password.Unwrap(), "$6$"))

// lisa's password should be left alone (already hashed)
assert.Equal(t, CryptPass, *options.Users["lisa"].Password)
assert.Equal(t, CryptPass, options.Users["lisa"].Password.Unwrap())

// maggie's password should now be nil (locked account)
assert.Nil(t, options.Users["maggie"].Password)
Expand All @@ -63,24 +63,24 @@ func TestNewUsersStageOptionsPassword(t *testing.T) {
func TestGenUsersStageSameAsNewUsersStageOptions(t *testing.T) {
users := []users.User{
{
Name: "user1", UID: common.ToPtr(1000), GID: common.ToPtr(1000),
Name: "user1", UID: types.Some(1000), GID: types.Some(1000),
Groups: []string{"grp1"},
Description: common.ToPtr("some-descr"),
Home: common.ToPtr("/home/user1"),
Shell: common.ToPtr("/bin/zsh"),
Key: common.ToPtr("some-key"),
Description: types.Some("some-descr"),
Home: types.Some("/home/user1"),
Shell: types.Some("/bin/zsh"),
Key: types.Some("some-key"),
},
}
expected := &UsersStageOptions{
Users: map[string]UsersStageOptionsUser{
"user1": {
UID: common.ToPtr(1000),
GID: common.ToPtr(1000),
UID: types.Some(1000),
GID: types.Some(1000),
Groups: []string{"grp1"},
Description: common.ToPtr("some-descr"),
Home: common.ToPtr("/home/user1"),
Shell: common.ToPtr("/bin/zsh"),
Key: common.ToPtr("some-key")},
Description: types.Some("some-descr"),
Home: types.Some("/home/user1"),
Shell: types.Some("/bin/zsh"),
Key: types.Some("some-key")},
},
}

Expand Down

0 comments on commit 23e0f8b

Please sign in to comment.