Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add password #2

Merged
merged 1 commit into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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("/root"))
Expect(got.Shell()).To(Equal("/bin/bash"))
Expect(got.Username()).To(Equal("root"))
Expect(got.RealName()).To(Equal("root"))
Expect(got.Password()).To(Equal("x"))
})

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
Loading