Skip to content

Commit

Permalink
[TIC-304] New Library Changes (#17)
Browse files Browse the repository at this point in the history
* feat(org): add change_role request (#10)

* [TIC-306] Add `ClearUserPassword` (#11)

* fix: add ChangeUserRoleInOrg to client interface

* feat(user): add ClearUserPassword

* feat(user): add /disable_2fa (#13)

* feat(org): add `org/remove_user` (#14)

* refactor(org): add argument for optional domain in update_org (#15)

* feat(org): add new CreateOrgV2 request (#16)

* fix: adjust return type for CreateOrgV2
  • Loading branch information
itailevi98 authored Oct 3, 2023
1 parent 8f3ebf3 commit ec6f2b3
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 2 deletions.
112 changes: 110 additions & 2 deletions pkg/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (
"strconv"

"encoding/json"
"github.com/google/uuid"
"net/url"

"github.com/google/uuid"

"github.com/propelauth/propelauth-go/pkg/helpers"
"github.com/propelauth/propelauth-go/pkg/models"
)
Expand Down Expand Up @@ -38,18 +39,23 @@ type ClientInterface interface {
UpdateUserPassword(userID uuid.UUID, params models.UpdateUserPasswordParam) (bool, error)
EnableUserCanCreateOrgs(userID uuid.UUID) (bool, error)
DisableUserCanCreateOrgs(userID uuid.UUID) (bool, error)
ClearUserPassword(userID uuid.UUID) (bool, error)
DisableUser2fa(userID uuid.UUID) (bool, error)

// org endpoints
AllowOrgToSetupSamlConnection(orgID uuid.UUID) (bool, error)
CreateOrg(name string) (*models.OrgMetadata, error)
CreateOrgV2(params models.CreateOrgV2Params) (*models.CreateOrgV2Response, error)
DeleteOrg(orgID uuid.UUID) (bool, error)
DisallowOrgToSetupSamlConnection(orgID uuid.UUID) (bool, error)
FetchOrg(orgID uuid.UUID) (*models.OrgMetadata, error)
FetchOrgByQuery(params models.OrgQueryParams) (*models.OrgList, error)
UpdateOrgMetadata(orgID uuid.UUID, params models.UpdateOrg) (bool, error)
ChangeUserRoleInOrg(params models.ChangeUserRoleInOrg) (bool, error)

// user in org endpoints
AddUserToOrg(params models.AddUserToOrg) (bool, error)
RemoveUserFromOrg(params models.RemoveUserFromOrg) (bool, error)
InviteUserToOrg(params models.InviteUserToOrg) (bool, error)
FetchUsersInOrg(orgID uuid.UUID, params models.UserInOrgQueryParams) (*models.UserList, error)

Expand Down Expand Up @@ -483,6 +489,22 @@ func (o *Client) UpdateUserEmail(userID uuid.UUID, params models.UpdateEmail) (b
return true, nil
}

// ClearUserPassword will clear a user's password.
func (o *Client) ClearUserPassword(userID uuid.UUID) (bool, error) {
urlPostfix := fmt.Sprintf("user/%s/clear_password", userID)

queryResponse, err := o.queryHelper.Put(o.integrationAPIKey, urlPostfix, nil, nil)
if err != nil {
return false, fmt.Errorf("Error on clearing user password: %w", err)
}

if err := o.returnErrorMessageIfNotOk(queryResponse); err != nil {
return false, fmt.Errorf("Error on clearing user password: %w", err)
}

return true, nil
}

// UpdateUserMetadata will update properties on a user. All fields are optional, we'll only update the ones
// that are provided.
func (o *Client) UpdateUserMetadata(userID uuid.UUID, params models.UpdateUserMetadata) (bool, error) {
Expand Down Expand Up @@ -628,6 +650,22 @@ func (o *Client) DisableUserCanCreateOrgs(userID uuid.UUID) (bool, error) {
return true, nil
}

// DisableUser2fa will disable 2fa for a user.
func (o *Client) DisableUser2fa(userID uuid.UUID) (bool, error) {
urlPostfix := fmt.Sprintf("user/%s/disable_2fa", userID)

queryResponse, err := o.queryHelper.Post(o.integrationAPIKey, urlPostfix, nil, nil)
if err != nil {
return false, fmt.Errorf("Error on disabling user 2fa: %w", err)
}

if err := o.returnErrorMessageIfNotOk(queryResponse); err != nil {
return false, fmt.Errorf("Error on disabling user 2fa: %w", err)
}

return true, nil
}

// public methods for users in orgs

// FetchUsersInOrg will fetch a paged list of users in an organization.
Expand Down Expand Up @@ -684,8 +722,51 @@ func (o *Client) AddUserToOrg(params models.AddUserToOrg) (bool, error) {
return true, nil
}

// RemoveUserFromOrg will remove the user from an org.
func (o *Client) RemoveUserFromOrg(params models.RemoveUserFromOrg) (bool, error) {
urlPostfix := "org/remove_user"

bodyJSON, err := json.Marshal(params)
if err != nil {
return false, fmt.Errorf("Error on marshalling body params: %w", err)
}

queryResponse, err := o.queryHelper.Post(o.integrationAPIKey, urlPostfix, nil, bodyJSON)
if err != nil {
return false, fmt.Errorf("Error on removing user from org: %w", err)
}

if err := o.returnErrorMessageIfNotOk(queryResponse); err != nil {
return false, fmt.Errorf("Error on removing user from org: %w", err)
}

return true, nil
}

// ChangeUserRole will change a user's role in an org.
func (o *Client) ChangeUserRoleInOrg(params models.ChangeUserRoleInOrg) (bool, error) {
urlPostfix := "org/change_role"

bodyJSON, err := json.Marshal(params)
if err != nil {
return false, fmt.Errorf("Error on marshalling body params: %w", err)
}

queryResponse, err := o.queryHelper.Post(o.integrationAPIKey, urlPostfix, nil, bodyJSON)
if err != nil {
return false, fmt.Errorf("Error on changing user role in org: %w", err)
}

if err := o.returnErrorMessageIfNotOk(queryResponse); err != nil {
return false, fmt.Errorf("Error on changing user role in org: %w", err)
}

return true, nil
}

// InviteUserToOrg will email a user and invite them to join an org. If they don't have an account
// yet, they'll be asked to make one, and will be able to join the org right afterwards.
//
// yet, they'll be asked to make one, and will be able to join the org right afterwards.
func (o *Client) InviteUserToOrg(params models.InviteUserToOrg) (bool, error) {
urlPostfix := "invite_user"

Expand Down Expand Up @@ -755,6 +836,7 @@ func (o *Client) FetchOrgByQuery(params models.OrgQueryParams) (*models.OrgList,
return orgs, nil
}

// NOTE: THIS IS DEPRECATED.
// CreateOrg will an organization and return its data, which is mostly just the org's ID.
func (o *Client) CreateOrg(name string) (*models.OrgMetadata, error) {
urlPostfix := "org/"
Expand Down Expand Up @@ -793,6 +875,32 @@ func (o *Client) CreateOrg(name string) (*models.OrgMetadata, error) {
return org, nil
}

// CreateOrgV2 is the updated version of CreateOrg. It will create an organization and return its data.
func (o *Client) CreateOrgV2(params models.CreateOrgV2Params) (*models.CreateOrgV2Response, error) {
urlPostfix := "org/"

bodyJSON, err := json.Marshal(params)
if err != nil {
return nil, fmt.Errorf("Error on marshalling body params: %w", err)
}

queryResponse, err := o.queryHelper.Post(o.integrationAPIKey, urlPostfix, nil, bodyJSON)
if err != nil {
return nil, fmt.Errorf("Error on creating org: %w", err)
}

if err := o.returnErrorMessageIfNotOk(queryResponse); err != nil {
return nil, fmt.Errorf("Error on creating org: %w", err)
}

org := &models.CreateOrgV2Response{}
if err := json.Unmarshal(queryResponse.BodyBytes, org); err != nil {
return nil, fmt.Errorf("Error on unmarshalling bytes to CreateOrgV2Response: %w", err)
}

return org, nil
}

// DeleteOrg will delete an organization.
func (o *Client) DeleteOrg(orgID uuid.UUID) (bool, error) {
urlPostfix := fmt.Sprintf("org/%s", orgID)
Expand Down
16 changes: 16 additions & 0 deletions pkg/models/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type UpdateOrg struct {
RestrictToDomain *bool `json:"restrict_to_domain"`
MaxUsers *int `json:"max_users"`
Metadata *map[string]interface{} `json:"metadata,omitempty"`
Domain *string `json:"domain,omitempty"`
}

// OrgQueryParams is the information for querying a pageable organization list. If left blank, PageSize
Expand All @@ -50,3 +51,18 @@ type OrgQueryParams struct {
PageNumber *int `json:"page_number,omitempty"`
OrderBy *string `json:"order_by,omitempty"`
}

// CreateOrgV2Params is the information needed to create an organization, as well as some optional fields.
type CreateOrgV2Params struct {
Name string `json:"name"`
Domain string `json:"domain,omitempty"`
EnableAutoJoiningByDomain bool `json:"enable_auto_joining_by_domain,omitempty"`
MembersMustHaveMatchingDomain bool `json:"members_must_have_matching_domain,omitempty"`
MaxUsers int `json:"max_users,omitempty"`
}

// CreateOrgV2Response is the information returned when creating an organization.
type CreateOrgV2Response struct {
OrgID uuid.UUID `json:"org_id"`
Name string `json:"name"`
}
15 changes: 15 additions & 0 deletions pkg/models/user_in_org.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ type AddUserToOrg struct {
Role string `json:"role"`
}

// RemoveUserFromOrg is the information needed to remove a user from an organization.
type RemoveUserFromOrg struct {
UserID uuid.UUID `json:"user_id"`
OrgID uuid.UUID `json:"org_id"`
}

// InviteUserToOrg is the information needed to invite a new user to join an organization. Role is
// just a string, but it has to match up to one of your defined roles, by default these are Owner,
// Admin, or Member, but they can be changed via your dashboard.
Expand All @@ -32,3 +38,12 @@ type InviteUserToOrg struct {
OrgID uuid.UUID `json:"org_id"`
Role string `json:"role"`
}

// ChangeUserRoleInOrg is the information needed to change a user's role in an organization. Role is
// just a string, but it has to match up to one of your defined roles, by default these are Owner,
// Admin, or Member, but they can be changed via your dashboard.
type ChangeUserRoleInOrg struct {
UserID uuid.UUID `json:"user_id"`
OrgID uuid.UUID `json:"org_id"`
Role string `json:"role"`
}

0 comments on commit ec6f2b3

Please sign in to comment.