github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/api/uaa/user.go (about)

     1  package uaa
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  	"net/url"
     9  
    10  	"code.cloudfoundry.org/cli/actor/actionerror"
    11  	"code.cloudfoundry.org/cli/api/uaa/internal"
    12  )
    13  
    14  // User represents an UAA user account.
    15  type User struct {
    16  	ID     string
    17  	Origin string
    18  }
    19  
    20  // newUserRequestBody represents the body of the request.
    21  type newUserRequestBody struct {
    22  	Username string   `json:"userName"`
    23  	Password string   `json:"password"`
    24  	Origin   string   `json:"origin"`
    25  	Name     userName `json:"name"`
    26  	Emails   []email  `json:"emails"`
    27  }
    28  
    29  type userName struct {
    30  	FamilyName string `json:"familyName"`
    31  	GivenName  string `json:"givenName"`
    32  }
    33  
    34  type email struct {
    35  	Value   string `json:"value"`
    36  	Primary bool   `json:"primary"`
    37  }
    38  
    39  // newUserResponse represents the HTTP JSON response.
    40  type newUserResponse struct {
    41  	ID     string `json:"id"`
    42  	Origin string `json:"origin"`
    43  }
    44  
    45  type paginatedUsersResponse struct {
    46  	Resources []newUserResponse `json:"resources"`
    47  }
    48  
    49  // CreateUser creates a new UAA user account with the provided password.
    50  func (client *Client) CreateUser(user string, password string, origin string) (User, error) {
    51  	userRequest := newUserRequestBody{
    52  		Username: user,
    53  		Password: password,
    54  		Origin:   origin,
    55  		Name: userName{
    56  			FamilyName: user,
    57  			GivenName:  user,
    58  		},
    59  		Emails: []email{
    60  			{
    61  				Value:   user,
    62  				Primary: true,
    63  			},
    64  		},
    65  	}
    66  
    67  	bodyBytes, err := json.Marshal(userRequest)
    68  	if err != nil {
    69  		return User{}, err
    70  	}
    71  
    72  	request, err := client.newRequest(requestOptions{
    73  		RequestName: internal.PostUserRequest,
    74  		Header: http.Header{
    75  			"Content-Type": {"application/json"},
    76  		},
    77  		Body: bytes.NewBuffer(bodyBytes),
    78  	})
    79  	if err != nil {
    80  		return User{}, err
    81  	}
    82  
    83  	var userResponse newUserResponse
    84  	response := Response{
    85  		Result: &userResponse,
    86  	}
    87  
    88  	err = client.connection.Make(request, &response)
    89  	if err != nil {
    90  		return User{}, err
    91  	}
    92  
    93  	return User(userResponse), nil
    94  }
    95  
    96  func (client *Client) DeleteUser(userGuid string) (User, error) {
    97  	deleteRequest, err := client.newRequest(requestOptions{
    98  		RequestName: internal.DeleteUserRequest,
    99  		Header: http.Header{
   100  			"Content-Type": {"application/json"},
   101  		},
   102  		URIParams: map[string]string{"user_guid": userGuid},
   103  	})
   104  
   105  	if err != nil {
   106  		return User{}, err
   107  	}
   108  
   109  	var deleteUserResponse newUserResponse
   110  	deleteResponse := Response{
   111  		Result: &deleteUserResponse,
   112  	}
   113  
   114  	err = client.connection.Make(deleteRequest, &deleteResponse)
   115  	if err != nil {
   116  		return User{}, err
   117  	}
   118  
   119  	return User(deleteUserResponse), nil
   120  }
   121  
   122  // ListUsers gets a list of users from UAA with the given username and (if provided) origin.
   123  // NOTE: that this is a paginated response and we are only currently returning the first page
   124  // of users. This will mean, if no origin is passed and there are more than 100 users with
   125  // the given username, only the first 100 will be returned. For our current purposes, this is
   126  // more than enough, but it would be a problem if we ever need to get all users with a username.
   127  func (client Client) ListUsers(userName, origin string) ([]User, error) {
   128  	filter := fmt.Sprintf(`userName eq "%s"`, userName)
   129  
   130  	if origin != "" {
   131  		filter = fmt.Sprintf(`%s and origin eq "%s"`, filter, origin)
   132  	}
   133  
   134  	request, err := client.newRequest(requestOptions{
   135  		RequestName: internal.ListUsersRequest,
   136  		Header: http.Header{
   137  			"Content-Type": {"application/json"},
   138  		},
   139  		Query: url.Values{
   140  			"filter": {filter},
   141  		},
   142  	})
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	var usersResponse paginatedUsersResponse
   148  	response := Response{
   149  		Result: &usersResponse,
   150  	}
   151  
   152  	err = client.connection.Make(request, &response)
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  
   157  	var users []User
   158  	for _, user := range usersResponse.Resources {
   159  		users = append(users, User(user))
   160  	}
   161  
   162  	return users, nil
   163  }
   164  
   165  func (client Client) ValidateClientUser(clientID string) error {
   166  	request, err := client.newRequest(requestOptions{
   167  		RequestName: internal.GetClientUser,
   168  		Header: http.Header{
   169  			"Content-Type": {"application/json"},
   170  		},
   171  		URIParams: map[string]string{"client_id": clientID},
   172  	})
   173  	if err != nil {
   174  		return err
   175  	}
   176  	err = client.connection.Make(request, &Response{})
   177  
   178  	if errType, ok := err.(RawHTTPStatusError); ok {
   179  		switch errType.StatusCode {
   180  		case http.StatusNotFound:
   181  			return actionerror.UserNotFoundError{Username: clientID}
   182  		case http.StatusForbidden:
   183  			return InsufficientScopeError{}
   184  		}
   185  	}
   186  
   187  	return err
   188  }