diff --git a/cmd/drupal_user.go b/cmd/drupal_user.go index 75f1f74..f54dc67 100644 --- a/cmd/drupal_user.go +++ b/cmd/drupal_user.go @@ -115,12 +115,12 @@ func (du drupalUser) checkCommonPassword(context wisski_distillery.Context, inst return err } - return status.RunErrorGroup(context.Stderr, status.Group[wstatus.User, error]{ - PrefixString: func(item wstatus.User, index int) string { + return status.RunErrorGroup(context.Stderr, status.Group[wstatus.DrupalUser, error]{ + PrefixString: func(item wstatus.DrupalUser, index int) string { return fmt.Sprintf("User[%q]: ", item.Name) }, PrefixAlign: true, - Handler: func(user wstatus.User, index int, writer io.Writer) error { + Handler: func(user wstatus.DrupalUser, index int, writer io.Writer) error { pv, err := users.GetPasswordValidator(context.Context, string(user.Name)) if err != nil { return err diff --git a/internal/status/wisski.go b/internal/status/wisski.go index c6acbe4..5a25e9a 100644 --- a/internal/status/wisski.go +++ b/internal/status/wisski.go @@ -36,7 +36,7 @@ type WissKI struct { NoPrefixes bool // TODO: Move this into the database Prefixes []string // list of prefixes Pathbuilders map[string]string // all the pathbuilders - Users []User // all the known users + Users []DrupalUser // all the known users Grants []models.Grant } diff --git a/internal/status/wisski_user.go b/internal/status/wisski_user.go index 9988e37..44df6f8 100644 --- a/internal/status/wisski_user.go +++ b/internal/status/wisski_user.go @@ -2,14 +2,16 @@ package status import ( "encoding/json" + "fmt" "strings" + "time" "github.com/FAU-CDI/wisski-distillery/internal/phpx" "golang.org/x/exp/slices" ) -// User represents a WissKI User -type User struct { +// DrupalUser represents a WissKI DrupalUser +type DrupalUser struct { UID phpx.Integer `json:"uid,omitempty"` Name phpx.String `json:"name,omitempty"` Mail phpx.String `json:"mail,omitempty"` @@ -21,6 +23,41 @@ type User struct { Roles UserRoles `json:"roles,omitempty"` } +func (du DrupalUser) String() string { + var builder strings.Builder + + builder.WriteString("DrupalUser{") + defer builder.WriteString("}") + + fmt.Fprintf(&builder, "UID: %d, ", du.UID) + fmt.Fprintf(&builder, "Name: %q, ", du.Name) + + if du.Mail != "" { + fmt.Fprintf(&builder, "Mail: %q, ", du.Mail) + } + + fmt.Fprintf(&builder, "Status: %t, ", du.Status) + + for _, tn := range []struct { + Name string + Time time.Time + }{ + {"Created", du.Created.Time()}, + {"Changed", du.Changed.Time()}, + {"Access", du.Access.Time()}, + {"Login", du.Login.Time()}, + } { + if tn.Time.IsZero() { + continue + } + fmt.Fprintf(&builder, "%s: %q, ", tn.Name, tn.Time.Format(time.Stamp)) + } + + fmt.Fprintf(&builder, "Roles: %s", du.Roles) + + return builder.String() +} + // UserRole represents the role of a user type UserRole string @@ -32,13 +69,12 @@ const ( // UserRoles represents a set of user roles for a given user type UserRoles map[UserRole]struct{} -// Has checks if the UserRole has the given role -func (ur UserRoles) Has(role UserRole) (ok bool) { - _, ok = ur[role] - return +func (ur UserRoles) String() string { + return "[" + ur.string() + "]" } -func (ur UserRoles) MarshalJSON() ([]byte, error) { +// String turns this UserRoles into a string +func (ur UserRoles) string() string { roles := make([]string, len(ur)) i := 0 for r := range ur { @@ -46,8 +82,17 @@ func (ur UserRoles) MarshalJSON() ([]byte, error) { i++ } slices.Sort(roles) // for consistent marshaling + return strings.Join(roles, ", ") +} - return json.Marshal(strings.Join(roles, ", ")) +func (ur UserRoles) MarshalJSON() ([]byte, error) { + return json.Marshal(ur.string()) +} + +// Has checks if the UserRole has the given role +func (ur UserRoles) Has(role UserRole) (ok bool) { + _, ok = ur[role] + return } func (u *UserRoles) UnmarshalJSON(data []byte) error { diff --git a/internal/wisski/ingredient/php/users/users.go b/internal/wisski/ingredient/php/users/users.go index d00f7f2..e68b13b 100644 --- a/internal/wisski/ingredient/php/users/users.go +++ b/internal/wisski/ingredient/php/users/users.go @@ -27,7 +27,7 @@ var ( var usersPHP string // All returns all known usernames -func (u *Users) All(ctx context.Context, server *phpx.Server) (users []status.User, err error) { +func (u *Users) All(ctx context.Context, server *phpx.Server) (users []status.DrupalUser, err error) { err = u.Dependencies.PHP.ExecScript(ctx, server, &users, usersPHP, "list_users") return }