Skip to content

Commit

Permalink
Add password
Browse files Browse the repository at this point in the history
Extend tests

Signed-off-by: Mauro Morales <[email protected]>
  • Loading branch information
mauromorales committed May 15, 2024
1 parent 401dc5e commit 11867f4
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 33 deletions.
7 changes: 7 additions & 0 deletions pkg/users/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type User interface {
GID() (int, error)
// Username returns the user's username
Username() string
// Password returns the user's password (this is usually not used but we include it for completeness)
Password() string
// HomeDir returns the user's home directory
HomeDir() string
// Shell returns the user's shell
Expand All @@ -25,6 +27,7 @@ type CommonUser struct {
uid string
gid string
username string
password string
homeDir string
shell string
realName string
Expand All @@ -42,6 +45,10 @@ func (u CommonUser) Username() string {
return u.username
}

func (u CommonUser) Password() string {
return u.password
}

func (u CommonUser) HomeDir() string {
return u.homeDir
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/users/users_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"strings"
)

// DarwinUser matches the fields in ds
type DarwinUser struct {
recordName string
password string
uniqueID string
primaryGroupID string
realName string
Expand All @@ -29,6 +31,10 @@ func (u DarwinUser) Username() string {
return u.recordName
}

func (u DarwinUser) Password() string {
return u.password
}

func (u DarwinUser) HomeDir() string {
return u.nFSHomeDirectory
}
Expand Down Expand Up @@ -62,7 +68,7 @@ func (l DarwinUserList) Load() error {
func (l DarwinUserList) GetAll() ([]User, error) {
users := make([]User, 0)

output, err := execDSCL("-readall", "/Users", "UniqueID", "PrimaryGroupID", "RealName", "UserShell", "NFSHomeDirectory", "RecordName")
output, err := execDSCL("-readall", "/Users", "UniqueID", "PrimaryGroupID", "RealName", "UserShell", "NFSHomeDirectory", "RecordName", "Password")
if err != nil {
return users, fmt.Errorf("failed to execute command: %w", err)
}
Expand Down Expand Up @@ -107,6 +113,8 @@ func parseRecord(record string) DarwinUser {
switch key {
case "RecordName":
user.recordName = val
case "Password":
user.password = val
case "UniqueID":
user.uniqueID = val
case "PrimaryGroupID":
Expand Down
36 changes: 36 additions & 0 deletions pkg/users/users_darwin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
var _ = Describe("ListDarwing", func() {
It("parse record", func() {
rootRecord := `NFSHomeDirectory: /var/root
Password: *
PrimaryGroupID: 0
RealName:
System Administrator
Expand All @@ -24,5 +25,40 @@ var _ = Describe("ListDarwing", func() {
Expect(got.Shell()).To(Equal("/bin/sh"))
Expect(got.Username()).To(Equal("root"))
Expect(got.RealName()).To(Equal("System Administrator"))
Expect(got.Password()).To(Equal("*"))
})
})

var _ = Describe("DarwinUser", func() {
Describe("Get", func() {
var list DarwinUserList
rootUser := DarwinUser{uniqueID: "0", primaryGroupID: "0", recordName: "root", password: "*", nFSHomeDirectory: "/root", userShell: "/bin/bash", realName: "root"}
barbazUser := DarwinUser{uniqueID: "1000", primaryGroupID: "1000", recordName: "barbaz", password: "*", nFSHomeDirectory: "/home/barbaz", userShell: "/bin/bash", realName: "Bar Baz"}
users := []User{rootUser, barbazUser}

Context("when the user is not present in the list", func() {
JustBeforeEach(func() {
list = DarwinUserList{}
})

It("returns nil", func() {
got := list.Get("foobar")
Expect(got).To(BeNil())
})
})

Context("when the user is present", func() {
JustBeforeEach(func() {
list = DarwinUserList{
CommonUserList{users: users, lastUID: 1000},
}
})

It("returns the user", func() {
got := list.Get("root")
Expect(got).To(Equal(rootUser))
Expect(list.GenerateUID()).To(Equal(1001))
})
})
})
})
61 changes: 35 additions & 26 deletions pkg/users/users_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import (
"strings"
)

// LinuxUser matches the fields in /etc/passwd. See man 5 passwd for more information
type LinuxUser struct {
login string
uid string
gid string
nameOrComment string
home string
shell string
interpreter string
login string
password string
uid string
gid string
userNameOrComment string
userHomeDir string
usercommandInterpreter string
}

func NewUserList() UserList {
Expand All @@ -40,16 +41,20 @@ func (u LinuxUser) Username() string {
return u.login
}

func (u LinuxUser) Password() string {
return u.password
}

func (u LinuxUser) HomeDir() string {
return u.home
return u.userHomeDir
}

func (u LinuxUser) Shell() string {
return u.shell
return u.usercommandInterpreter
}

func (u LinuxUser) RealName() string {
return u.nameOrComment
return u.userNameOrComment
}

func (l *LinuxUserList) SetPath(path string) {
Expand Down Expand Up @@ -78,23 +83,8 @@ func (l *LinuxUserList) GetAll() ([]User, error) {
for scanner.Scan() {
line := scanner.Text()

// Split the line into parts using ':' as the delimiter
parts := strings.Split(line, ":")
user, err := parseRecord(line)

// Check if the line is correctly formatted with 7 fields
if len(parts) != 7 {
return users, fmt.Errorf("unexpected format: %s", line)
}

user := LinuxUser{
login: parts[0],
uid: parts[2],
gid: parts[3],
nameOrComment: parts[4],
home: parts[5],
shell: parts[6],
interpreter: parts[6],
}
users = append(users, user)

uid, err := user.UID()
Expand All @@ -116,3 +106,22 @@ func (l *LinuxUserList) GetAll() ([]User, error) {

return users, nil
}

func parseRecord(record string) (LinuxUser, error) {
user := LinuxUser{}
fields := strings.Split(record, ":")
// Check if the line is correctly formatted with 7 fields
if len(fields) != 7 {
return user, fmt.Errorf("unexpected format: %s", record)
}

user.login = fields[0]
user.password = fields[1]
user.uid = fields[2]
user.gid = fields[3]
user.userNameOrComment = fields[4]
user.userHomeDir = fields[5]
user.usercommandInterpreter = fields[6]

return user, nil
}
87 changes: 87 additions & 0 deletions pkg/users/users_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package users

import (
"log"
"os"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("LinuxUserList", func() {
It("parses a record", func() {
rootRecord := `root:x:0:0:root:/root:/bin/bash`

got, err := parseRecord(rootRecord)
Expect(err).To(BeNil())

Expect(got.UID()).To(Equal(0))
Expect(got.GID()).To(Equal(0))
Expect(got.HomeDir()).To(Equal("/var/root"))

Check failure on line 20 in pkg/users/users_linux_test.go

View workflow job for this annotation

GitHub Actions / Go oldstable

It 05/15/24 07:27:08.267

Check failure on line 20 in pkg/users/users_linux_test.go

View workflow job for this annotation

GitHub Actions / Go stable

It 05/15/24 07:27:10.23

Check failure on line 20 in pkg/users/users_linux_test.go

View workflow job for this annotation

GitHub Actions / Go oldstable

It 05/15/24 07:27:16.985

Check failure on line 20 in pkg/users/users_linux_test.go

View workflow job for this annotation

GitHub Actions / Go stable

It 05/15/24 07:27:17.491
Expect(got.Shell()).To(Equal("/bin/sh"))
Expect(got.Username()).To(Equal("root"))
Expect(got.RealName()).To(Equal("System Administrator"))
Expect(got.Password()).To(Equal("*"))
})

It("Gets all users", func() {
file, err := os.CreateTemp("", "passwd")
if err != nil {
log.Fatal(err)
}
defer os.Remove(file.Name())

_, err = file.WriteString("root:x:0:0:root:/root:/bin/bash\n")
Expect(err).ToNot(HaveOccurred())
_, err = file.WriteString("foo:x:1000:1000:foo:/home/foo:/bin/bash\n")
Expect(err).ToNot(HaveOccurred())

list := LinuxUserList{}
list.SetPath(file.Name())
err = list.Load()
Expect(err).ToNot(HaveOccurred())

user := list.Get("root")
Expect(user).ToNot(BeNil())
user = list.Get("foo")
Expect(user).ToNot(BeNil())
user = list.Get("bar")
Expect(user).To(BeNil())
Expect(list.GenerateUID()).To(Equal(1001))
})
})

var _ = Describe("DarwinUser", func() {
Describe("Get", func() {
var list LinuxUserList
rootUser := LinuxUser{uid: "0", gid: "0", login: "root", password: "*", userHomeDir: "/root", usercommandInterpreter: "/bin/bash", userNameOrComment: "root"}
barbazUser := LinuxUser{uid: "1000", gid: "1000", login: "barbaz", password: "*", userHomeDir: "/home/barbaz", usercommandInterpreter: "/bin/bash", userNameOrComment: "Bar Baz"}
users := []User{rootUser, barbazUser}

Context("when the user is not present in the list", func() {
JustBeforeEach(func() {
list = LinuxUserList{}
})

It("returns nil", func() {
got := list.Get("foobar")
Expect(got).To(BeNil())
})
})

Context("when the user is present", func() {
JustBeforeEach(func() {
list = LinuxUserList{
CommonUserList: CommonUserList{users: users, lastUID: 1000},
path: "/etc/passwd",
}
})

It("returns the user", func() {
got := list.Get("root")
Expect(got).To(Equal(rootUser))
Expect(list.GenerateUID()).To(Equal(1001))
})
})
})
})
14 changes: 8 additions & 6 deletions pkg/users/users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
var _ = Describe("users", func() {
Describe("Get", func() {
var list CommonUserList
user := CommonUser{uid: "0", gid: "0", username: "root", homeDir: "/root", shell: "/bin/bash", realName: "root"}
users := []User{user}
rootUser := CommonUser{uid: "0", gid: "0", username: "root", homeDir: "/root", shell: "/bin/bash", realName: "root"}
barbazUser := CommonUser{uid: "1000", gid: "1000", username: "barbaz", homeDir: "/home/barbaz", shell: "/bin/bash", realName: "Bar Baz"}
users := []User{rootUser, barbazUser}

Context("when the user is not present in the list", func() {
JustBeforeEach(func() {
Expand All @@ -29,15 +30,16 @@ var _ = Describe("users", func() {

It("returns the user", func() {
got := list.Get("root")
Expect(got).To(Equal(user))
Expect(got).To(Equal(rootUser))
})
})
})

Describe("GenerateUID", func() {
var list CommonUserList
user := CommonUser{uid: "0", gid: "0", username: "root", homeDir: "/root", shell: "/bin/bash", realName: "root"}
users := []User{user}
foobar := CommonUser{uid: "1000", gid: "1000", username: "foobar", homeDir: "/home/foobar", shell: "/bin/bash", realName: "foo bar"}
users := []User{user, foobar}

Context("when the list is empty", func() {
JustBeforeEach(func() {
Expand All @@ -52,12 +54,12 @@ var _ = Describe("users", func() {

Context("when the list is not empty", func() {
JustBeforeEach(func() {
list = CommonUserList{users: users}
list = CommonUserList{users: users, lastUID: 1000}
})

It("returns the next available UID", func() {
got := list.GenerateUID()
Expect(got).To(Equal(1))
Expect(got).To(Equal(1001))
})
})
})
Expand Down

0 comments on commit 11867f4

Please sign in to comment.