diff --git a/cmd/user.go b/cmd/user.go index 55ac4c3..43301c6 100644 --- a/cmd/user.go +++ b/cmd/user.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/onelogin/onelogin-go-sdk/v4/pkg/onelogin/models" "github.com/pepabo/onecli/onelogin" "github.com/pepabo/onecli/utils" "github.com/spf13/cobra" @@ -109,10 +110,42 @@ var modifyEmailCmd = &cobra.Command{ }, } +var addCmd = &cobra.Command{ + Use: "add ", + Short: "Add a new user", + Long: `Add a new user to your OneLogin organization`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + firstName := args[0] + lastName := args[1] + email := args[2] + + client, err := initClient() + if err != nil { + return fmt.Errorf("error initializing OneLogin client: %v", err) + } + + newUser := models.User{ + Firstname: firstName, + Lastname: lastName, + Email: email, + } + + createdUser, err := client.CreateUser(newUser) + if err != nil { + return fmt.Errorf("error creating user: %v", err) + } + + fmt.Printf("Successfully added user: %s %s with email: %s\n", createdUser.Firstname, createdUser.Lastname, createdUser.Email) + return nil + }, +} + func init() { userCmd.AddCommand(listCmd) userCmd.AddCommand(modifyCmd) modifyCmd.AddCommand(modifyEmailCmd) + userCmd.AddCommand(addCmd) listCmd.Flags().StringVarP(&output, "output", "o", "yaml", "Output format (yaml, json)") listCmd.Flags().StringVar(&queryParams.Email, "email", "", "Filter users by email") diff --git a/onelogin/client.go b/onelogin/client.go index c432977..d72f142 100644 --- a/onelogin/client.go +++ b/onelogin/client.go @@ -14,6 +14,7 @@ const ( type OneloginClient interface { GetUsers(query models.Queryable) (interface{}, error) UpdateUser(userID int, user models.User) (interface{}, error) + CreateUser(user models.User) (interface{}, error) } // Onelogin represents the Onelogin client diff --git a/onelogin/user.go b/onelogin/user.go index e5ae638..4bfc003 100644 --- a/onelogin/user.go +++ b/onelogin/user.go @@ -1,7 +1,9 @@ package onelogin import ( + "fmt" "strconv" + "time" "github.com/onelogin/onelogin-go-sdk/v4/pkg/onelogin/models" "github.com/pepabo/onecli/utils" @@ -55,3 +57,43 @@ func (o *Onelogin) GetUsers(query UserQuery) ([]models.User, error) { func (o *Onelogin) UpdateUser(userID int, user models.User) (interface{}, error) { return o.client.UpdateUser(userID, user) } + +// SetUserState sets the user state to active and updates the last login time +func (o *Onelogin) SetUserState(userID int) error { + user := models.User{ + Status: 1, // 1はアクティブを示す + LastLogin: time.Now(), + } + _, err := o.UpdateUser(userID, user) + if err != nil { + return fmt.Errorf("error setting user state: %v", err) + } + return nil +} + +// CreateUser creates a new user in Onelogin +func (o *Onelogin) CreateUser(user models.User) (models.User, error) { + createdUserInterface, err := o.client.CreateUser(user) + if err != nil { + return models.User{}, fmt.Errorf("error creating user: %v", err) + } + + createdUserMap, ok := createdUserInterface.(map[string]interface{}) + if !ok { + return models.User{}, fmt.Errorf("error asserting created user to map[string]interface{}") + } + + createdUser := models.User{ + ID: int32(createdUserMap["id"].(float64)), + Email: createdUserMap["email"].(string), + Firstname: createdUserMap["firstname"].(string), + Lastname: createdUserMap["lastname"].(string), + } + + // ユーザーのステータスをアクティブに設定し、最終ログイン日時を更新 + if err := o.SetUserState(int(createdUser.ID)); err != nil { + return models.User{}, err + } + + return createdUser, nil +} diff --git a/onelogin/user_test.go b/onelogin/user_test.go index ebf2d67..6ccb6e3 100644 --- a/onelogin/user_test.go +++ b/onelogin/user_test.go @@ -24,6 +24,11 @@ func (m *MockClient) UpdateUser(userID int, user models.User) (interface{}, erro return args.Get(0), args.Error(1) } +func (m *MockClient) CreateUser(user models.User) (interface{}, error) { + args := m.Called(user) + return args.Get(0), args.Error(1) +} + func TestGetUsers(t *testing.T) { tests := []struct { name string @@ -149,3 +154,72 @@ func TestGetUsers(t *testing.T) { }) } } + +func TestCreateUser(t *testing.T) { + tests := []struct { + name string + inputUser models.User + mockResponse interface{} + mockError error + expectedUser models.User + expectedError error + }{ + { + name: "successful user creation", + inputUser: models.User{ + Email: "newuser@example.com", + Username: "newuser", + Firstname: "New", + Lastname: "User", + }, + mockResponse: map[string]interface{}{ + "id": 3, + "email": "newuser@example.com", + "username": "newuser", + "firstname": "New", + "lastname": "User", + }, + expectedUser: models.User{ + ID: 3, + Email: "newuser@example.com", + Username: "newuser", + Firstname: "New", + Lastname: "User", + }, + }, + { + name: "error creating user", + inputUser: models.User{ + Email: "erroruser@example.com", + Username: "erroruser", + Firstname: "Error", + Lastname: "User", + }, + mockError: assert.AnError, + expectedError: assert.AnError, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockClient := new(MockClient) + o := &Onelogin{ + client: mockClient, + } + + mockClient.On("CreateUser", tt.inputUser).Return(tt.mockResponse, tt.mockError) + + createdUser, err := o.CreateUser(tt.inputUser) + + if tt.expectedError != nil { + assert.Error(t, err) + assert.Equal(t, tt.expectedError, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedUser, createdUser) + } + + mockClient.AssertExpectations(t) + }) + } +}