github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/identity/v3/roles/requests.go (about)

     1  package roles
     2  
     3  import (
     4  	"github.com/chnsz/golangsdk"
     5  	"github.com/chnsz/golangsdk/pagination"
     6  )
     7  
     8  // ListOptsBuilder allows extensions to add additional parameters to
     9  // the List request
    10  type ListOptsBuilder interface {
    11  	ToRoleListQuery() (string, error)
    12  }
    13  
    14  // ListOpts provides options to filter the List results.
    15  type ListOpts struct {
    16  	// DomainID filters the response by a domain ID.
    17  	// If this parameter is specified, only custom policies of the account will be returned.
    18  	// If not specified, all system permissions (including system-defined policies and roles) will be returned.
    19  	DomainID string `q:"domain_id"`
    20  
    21  	// Name filters the response by role name.
    22  	Name string `q:"name"`
    23  
    24  	DisplayName string `q:"display_name"`
    25  
    26  	// This parameter is valid only when domain_id is left blank.
    27  	// policy: system-defined policy; role: system-defined role
    28  	PermissionType string `q:"permission_type"`
    29  
    30  	// The number of pages of data for paging query, the minimum value is 1.
    31  	// Need to exist at the same time as "PerPage" parameter. When the "DomainID" parameter is passed in to query the
    32  	// custom policies, it can be used together.
    33  	Page int `q:"page"`
    34  
    35  	// The number of data per page in paging query, the value range is from 1 to 300, the default value is 300.
    36  	// It needs to exist at the same time as "Page" parameter. When the "Page" and "PerPage" parameters are not passed,
    37  	// a maximum of 300 permissions are returned per page.
    38  	PerPage int `q:"per_page"`
    39  
    40  	// Display mode of the permission. The options include domain, project, and all.
    41  	Type string `q:"type"`
    42  
    43  	// Service catalog, which corresponds to the catalog field in policies.
    44  	Catalog string `q:"catalog"`
    45  }
    46  
    47  // ToRoleListQuery formats a ListOpts into a query string.
    48  func (opts ListOpts) ToRoleListQuery() (string, error) {
    49  	q, err := golangsdk.BuildQueryString(opts)
    50  	return q.String(), err
    51  }
    52  
    53  // List enumerates the roles to which the current token has access.
    54  //
    55  // Deprecated: AllPages will not work due to the links.next field is always null in API response.
    56  // please use ListWithPages instead.
    57  func List(client *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager {
    58  	url := listURL(client)
    59  	if opts != nil {
    60  		query, err := opts.ToRoleListQuery()
    61  		if err != nil {
    62  			return pagination.Pager{Err: err}
    63  		}
    64  		url += query
    65  	}
    66  
    67  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
    68  		return RolePage{pagination.LinkedPageBase{PageResult: r}}
    69  	})
    70  }
    71  
    72  // ListWithPages is a method to query role pages via page size and page number.
    73  func ListWithPages(client *golangsdk.ServiceClient, opts ListOpts) pagination.Pager {
    74  	url := listURL(client)
    75  	if opts.PerPage == 0 {
    76  		opts.PerPage = 300
    77  	}
    78  	if opts.Page == 0 {
    79  		opts.Page = 1
    80  	}
    81  
    82  	query, err := opts.ToRoleListQuery()
    83  	if err != nil {
    84  		return pagination.Pager{Err: err}
    85  	}
    86  	url += query
    87  
    88  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
    89  		return RoleOffsetPage{pagination.OffsetPageBase{PageResult: r}}
    90  	})
    91  }
    92  
    93  // Get retrieves details on a single role, by ID.
    94  func Get(client *golangsdk.ServiceClient, id string) (r GetResult) {
    95  	_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
    96  	return
    97  }
    98  
    99  // CreateOptsBuilder allows extensions to add additional parameters to
   100  // the Create request.
   101  type CreateOptsBuilder interface {
   102  	ToRoleCreateMap() (map[string]interface{}, error)
   103  }
   104  
   105  // CreateOpts provides options used to create a role.
   106  type CreateOpts struct {
   107  	// Name is the name of the new role.
   108  	Name string `json:"name" required:"true"`
   109  
   110  	// DomainID is the ID of the domain the role belongs to.
   111  	DomainID string `json:"domain_id,omitempty"`
   112  
   113  	// Extra is free-form extra key/value pairs to describe the role.
   114  	Extra map[string]interface{} `json:"-"`
   115  }
   116  
   117  // ToRoleCreateMap formats a CreateOpts into a create request.
   118  func (opts CreateOpts) ToRoleCreateMap() (map[string]interface{}, error) {
   119  	b, err := golangsdk.BuildRequestBody(opts, "role")
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	if opts.Extra != nil {
   125  		if v, ok := b["role"].(map[string]interface{}); ok {
   126  			for key, value := range opts.Extra {
   127  				v[key] = value
   128  			}
   129  		}
   130  	}
   131  
   132  	return b, nil
   133  }
   134  
   135  // Create creates a new Role.
   136  func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   137  	b, err := opts.ToRoleCreateMap()
   138  	if err != nil {
   139  		r.Err = err
   140  		return
   141  	}
   142  	_, r.Err = client.Post(createURL(client), &b, &r.Body, &golangsdk.RequestOpts{
   143  		OkCodes: []int{201},
   144  	})
   145  	return
   146  }
   147  
   148  // UpdateOptsBuilder allows extensions to add additional parameters to
   149  // the Update request.
   150  type UpdateOptsBuilder interface {
   151  	ToRoleUpdateMap() (map[string]interface{}, error)
   152  }
   153  
   154  // UpdateOpts provides options for updating a role.
   155  type UpdateOpts struct {
   156  	// Name is the name of the new role.
   157  	Name string `json:"name,omitempty"`
   158  
   159  	// Extra is free-form extra key/value pairs to describe the role.
   160  	Extra map[string]interface{} `json:"-"`
   161  }
   162  
   163  // ToRoleUpdateMap formats a UpdateOpts into an update request.
   164  func (opts UpdateOpts) ToRoleUpdateMap() (map[string]interface{}, error) {
   165  	b, err := golangsdk.BuildRequestBody(opts, "role")
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  
   170  	if opts.Extra != nil {
   171  		if v, ok := b["role"].(map[string]interface{}); ok {
   172  			for key, value := range opts.Extra {
   173  				v[key] = value
   174  			}
   175  		}
   176  	}
   177  
   178  	return b, nil
   179  }
   180  
   181  // Update updates an existing Role.
   182  func Update(client *golangsdk.ServiceClient, roleID string, opts UpdateOptsBuilder) (r UpdateResult) {
   183  	b, err := opts.ToRoleUpdateMap()
   184  	if err != nil {
   185  		r.Err = err
   186  		return
   187  	}
   188  	_, r.Err = client.Patch(updateURL(client, roleID), &b, &r.Body, &golangsdk.RequestOpts{
   189  		OkCodes: []int{200},
   190  	})
   191  	return
   192  }
   193  
   194  // Delete deletes a role.
   195  func Delete(client *golangsdk.ServiceClient, roleID string) (r DeleteResult) {
   196  	_, r.Err = client.Delete(deleteURL(client, roleID), nil)
   197  	return
   198  }
   199  
   200  // ListAssignmentsOptsBuilder allows extensions to add additional parameters to
   201  // the ListAssignments request.
   202  type ListAssignmentsOptsBuilder interface {
   203  	extractAssignment() (string, string, string, string, error)
   204  }
   205  
   206  // ListAssignmentsOpts allows you to query the ListAssignments method.
   207  // Specify one of or a combination of GroupId, RoleId, ScopeDomainId,
   208  // ScopeProjectId, and/or UserId to search for roles assigned to corresponding
   209  // entities.
   210  type ListAssignmentsOpts struct {
   211  	// GroupID is the group ID to query.
   212  	GroupID string `q:"group.id"`
   213  
   214  	// ScopeDomainID filters the results by the given domain ID.
   215  	ScopeDomainID string `q:"scope.domain.id"`
   216  
   217  	// ScopeProjectID filters the results by the given Project ID.
   218  	ScopeProjectID string `q:"scope.project.id"`
   219  
   220  	// UserID filterst he results by the given User ID.
   221  	UserID string `q:"user.id"`
   222  }
   223  
   224  // ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string.
   225  func (opts ListAssignmentsOpts) extractAssignment() (string, string, string, string, error) {
   226  	// Get corresponding URL
   227  	var targetID string
   228  	var targetType string
   229  	if opts.ScopeProjectID != "" {
   230  		targetID = opts.ScopeProjectID
   231  		targetType = "projects"
   232  	} else {
   233  		targetID = opts.ScopeDomainID
   234  		targetType = "domains"
   235  	}
   236  
   237  	var actorID string
   238  	var actorType string
   239  	if opts.UserID != "" {
   240  		actorID = opts.UserID
   241  		actorType = "users"
   242  	} else {
   243  		actorID = opts.GroupID
   244  		actorType = "groups"
   245  	}
   246  
   247  	return targetType, targetID, actorType, actorID, nil
   248  }
   249  
   250  // ListAssignments enumerates the roles assigned to a specified resource.
   251  func ListAssignments(client *golangsdk.ServiceClient, opts ListAssignmentsOptsBuilder) pagination.Pager {
   252  	targetType, targetID, actorType, actorID, _ := opts.extractAssignment()
   253  
   254  	url := listAssignmentsURL(client, targetType, targetID, actorType, actorID)
   255  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
   256  		return RoleAssignmentPage{pagination.LinkedPageBase{PageResult: r}}
   257  	})
   258  }
   259  
   260  // AssignOpts provides options to assign a role
   261  type AssignOpts struct {
   262  	// UserID is the ID of a user to assign a role
   263  	// Note: exactly one of UserID or GroupID must be provided
   264  	UserID string `xor:"GroupID"`
   265  
   266  	// GroupID is the ID of a group to assign a role
   267  	// Note: exactly one of UserID or GroupID must be provided
   268  	GroupID string `xor:"UserID"`
   269  
   270  	// ProjectID is the ID of a project to assign a role on
   271  	// Note: exactly one of ProjectID or DomainID must be provided
   272  	ProjectID string `xor:"DomainID"`
   273  
   274  	// DomainID is the ID of a domain to assign a role on
   275  	// Note: exactly one of ProjectID or DomainID must be provided
   276  	DomainID string `xor:"ProjectID"`
   277  }
   278  
   279  // UnassignOpts provides options to unassign a role
   280  type UnassignOpts struct {
   281  	// UserID is the ID of a user to unassign a role
   282  	// Note: exactly one of UserID or GroupID must be provided
   283  	UserID string `xor:"GroupID"`
   284  
   285  	// GroupID is the ID of a group to unassign a role
   286  	// Note: exactly one of UserID or GroupID must be provided
   287  	GroupID string `xor:"UserID"`
   288  
   289  	// ProjectID is the ID of a project to unassign a role on
   290  	// Note: exactly one of ProjectID or DomainID must be provided
   291  	ProjectID string `xor:"DomainID"`
   292  
   293  	// DomainID is the ID of a domain to unassign a role on
   294  	// Note: exactly one of ProjectID or DomainID must be provided
   295  	DomainID string `xor:"ProjectID"`
   296  }
   297  
   298  // Assign is the operation responsible for assigning a role
   299  // to a user/group on a project/domain.
   300  func Assign(client *golangsdk.ServiceClient, roleID string, opts AssignOpts) (r AssignmentResult) {
   301  	// Check xor conditions
   302  	_, err := golangsdk.BuildRequestBody(opts, "")
   303  	if err != nil {
   304  		r.Err = err
   305  		return
   306  	}
   307  
   308  	// Get corresponding URL
   309  	var targetID string
   310  	var targetType string
   311  	if opts.ProjectID != "" {
   312  		targetID = opts.ProjectID
   313  		targetType = "projects"
   314  	} else {
   315  		targetID = opts.DomainID
   316  		targetType = "domains"
   317  	}
   318  
   319  	var actorID string
   320  	var actorType string
   321  	if opts.UserID != "" {
   322  		actorID = opts.UserID
   323  		actorType = "users"
   324  	} else {
   325  		actorID = opts.GroupID
   326  		actorType = "groups"
   327  	}
   328  
   329  	_, r.Err = client.Put(assignURL(client, targetType, targetID, actorType, actorID, roleID), nil, nil, &golangsdk.RequestOpts{
   330  		OkCodes: []int{204},
   331  	})
   332  	return
   333  }
   334  
   335  // Unassign is the operation responsible for unassigning a role
   336  // from a user/group on a project/domain.
   337  func Unassign(client *golangsdk.ServiceClient, roleID string, opts UnassignOpts) (r UnassignmentResult) {
   338  	// Check xor conditions
   339  	_, err := golangsdk.BuildRequestBody(opts, "")
   340  	if err != nil {
   341  		r.Err = err
   342  		return
   343  	}
   344  
   345  	// Get corresponding URL
   346  	var targetID string
   347  	var targetType string
   348  	if opts.ProjectID != "" {
   349  		targetID = opts.ProjectID
   350  		targetType = "projects"
   351  	} else {
   352  		targetID = opts.DomainID
   353  		targetType = "domains"
   354  	}
   355  
   356  	var actorID string
   357  	var actorType string
   358  	if opts.UserID != "" {
   359  		actorID = opts.UserID
   360  		actorType = "users"
   361  	} else {
   362  		actorID = opts.GroupID
   363  		actorType = "groups"
   364  	}
   365  
   366  	_, r.Err = client.Delete(assignURL(client, targetType, targetID, actorType, actorID, roleID), &golangsdk.RequestOpts{
   367  		OkCodes: []int{204},
   368  	})
   369  	return
   370  }
   371  
   372  // AssignAllResources is the operation responsible for granting a user group permissions for all resources,
   373  // including those in enterprise projects, region-specific projects, and global services.
   374  func AssignAllResources(client *golangsdk.ServiceClient, domainID, groupID, roleID string) (r AssignmentResult) {
   375  	_, r.Err = client.Put(assignInheritedURL(client, domainID, groupID, roleID), nil, nil, &golangsdk.RequestOpts{
   376  		OkCodes: []int{204},
   377  	})
   378  	return
   379  }
   380  
   381  // UnassignAllResources is the operation responsible for unassigning a user group permissions for all resources.
   382  func UnassignAllResources(client *golangsdk.ServiceClient, domainID, groupID, roleID string) (r AssignmentResult) {
   383  	_, r.Err = client.Delete(assignInheritedURL(client, domainID, groupID, roleID), &golangsdk.RequestOpts{
   384  		OkCodes: []int{204},
   385  	})
   386  	return
   387  }
   388  
   389  // CheckAllResourcesPermission is provided for the administrator to check whether a user group has specified permissions for all resources.
   390  func CheckAllResourcesPermission(client *golangsdk.ServiceClient, domainID, groupID, roleID string) (r CheckResult) {
   391  	_, r.Err = client.Head(assignInheritedURL(client, domainID, groupID, roleID), &golangsdk.RequestOpts{
   392  		OkCodes: []int{204},
   393  	})
   394  	return
   395  }