├── .github ├── dependabot.yml └── workflows │ ├── ci.yaml │ └── release.yaml ├── .gitignore ├── .goreleaser.yaml ├── LICENSE ├── README.md ├── apiclient.go ├── client.go ├── config.go ├── error.go ├── examples └── live_test.go ├── feature.go ├── feature └── client.go ├── go.mod ├── go.sum ├── list.go ├── middleware.go ├── object └── client.go ├── objecttype.go ├── objecttype └── client.go ├── params.go ├── permission.go ├── permission └── client.go ├── pricingtier.go ├── pricingtier └── client.go ├── query.go ├── role.go ├── role └── client.go ├── session.go ├── session └── client.go ├── tenant.go ├── tenant └── client.go ├── user.go ├── user └── client.go └── warrant.go /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Warrant Go 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 2 16 | - name: Setup Go Env 17 | uses: actions/setup-go@v4 18 | with: 19 | go-version: "^1.22.0" 20 | - name: Verify 21 | run: go mod verify 22 | - name: Build 23 | run: go build 24 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Warrant Go 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v[0-9]+.[0-9]+.[0-9]+' 7 | jobs: 8 | release: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Setup Go Env 12 | uses: actions/setup-go@v4 13 | with: 14 | go-version: "^1.22.0" 15 | - name: Checkout 16 | uses: actions/checkout@v3 17 | - name: Release with GoReleaser 18 | uses: goreleaser/goreleaser-action@v4 19 | with: 20 | distribution: goreleaser 21 | version: latest 22 | args: release --clean 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .DS_Store 3 | warrant 4 | /examples/main 5 | dist/ 6 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | before: 2 | hooks: 3 | - go mod tidy 4 | builds: 5 | - skip: true 6 | changelog: 7 | sort: asc 8 | filters: 9 | exclude: 10 | - '^docs:' 11 | - '^test:' 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Warrant (Forerunner Labs, Inc.) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Warrant Go Library 2 | 3 | Use [Warrant](https://warrant.dev/) in server-side Go projects. 4 | 5 | ## Installation 6 | 7 | ```shell 8 | go get github.com/warrant-dev/warrant-go/v6 9 | ``` 10 | 11 | ## Usage 12 | 13 | You can use the Warrant SDK with or without a client. Instantiating a client allows you to create different client instances each with their own config (API key, API endpoint, etc). 14 | 15 | ### Without a Client 16 | 17 | ```go 18 | import "github.com/warrant-dev/warrant-go/v6" 19 | 20 | // Setup 21 | warrant.ApiKey = "api_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=" 22 | 23 | // Create warrant 24 | warrant, err := warrant.Create(&warrant.WarrantParams{}) 25 | 26 | // Create tenant 27 | tenant, err := tenant.Create(&tenant.TenantParams{}) 28 | ``` 29 | 30 | ### With a Client 31 | 32 | Instantiate the Warrant client with your API key to get started: 33 | ```go 34 | import "github.com/warrant-dev/warrant-go/v6" 35 | import "github.com/warrant-dev/warrant-go/v6/config" 36 | 37 | client := warrant.NewClient(config.ClientConfig{ 38 | ApiKey: "api_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=", 39 | ApiEndpoint: "https://api.warrant.dev", 40 | AuthorizeEndpoint: "https://api.warrant.dev", 41 | SelfServiceDashEndpoint: "https://self-serve.warrant.dev", 42 | }) 43 | ``` 44 | 45 | ## Configuring Endpoints 46 | The API, Authorize, Self-Service endpoints and http client are configurable via the `warrant.ApiEndpoint`, `warrant.AuthorizeEndpoint`, `warrant.SelfServiceDashEndpoint`, and `warrant.HttpClient` attributes: 47 | 48 | ```go 49 | import "github.com/warrant-dev/warrant-go/v6" 50 | import "github.com/warrant-dev/warrant-go/v6/config" 51 | 52 | // Without client initialization 53 | // Set api and authorize endpoints to http://localhost:8000 54 | // Set http client to a http.Client instance returned by yourHttpClient() 55 | warrant.ApiEndpoint = "http://localhost:8000" 56 | warrant.AuthorizeEndpoint = "http://localhost:8000" 57 | warrant.HttpClient = yourHttpClient() 58 | 59 | // With client initialization 60 | // Set api and authorize endpoints to http://localhost:8000 and self-service endpoint to http://localhost:8080 61 | // Set http client to a http.Client instance returned by yourHttpClient() 62 | client := warrant.NewClient(config.ClientConfig{ 63 | ApiKey: "api_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=", 64 | ApiEndpoint: "http://localhost:8000", 65 | AuthorizeEndpoint: "http://localhost:8000", 66 | SelfServiceDashEndpoint: "http://localhost:8080", 67 | HttpClient: yourHttpClient(), 68 | }) 69 | ``` 70 | 71 | ## Examples 72 | 73 | ### Users 74 | 75 | ```go 76 | // Create 77 | createdUser, err := user.Create(&warrant.UserParams{ 78 | UserId: "userId", 79 | }) 80 | 81 | // Get 82 | user, err := user.Get("userId") 83 | 84 | 85 | // Delete 86 | err = user.Delete("userId") 87 | ``` 88 | 89 | ### Warrants 90 | 91 | ```go 92 | 93 | // Create 94 | createdWarrant, err := warrant.Create(&warrant.WarrantParams{ 95 | ObjectType: "tenant", 96 | ObjectId: "1", 97 | Relation: "member", 98 | Subject: warrant.Subject{ 99 | ObjectType: "user", 100 | ObjectId: "1", 101 | }, 102 | }) 103 | 104 | // Delete 105 | err = warrant.Delete(&warrant.WarrantParams{ 106 | ObjectType: "tenant", 107 | ObjectId: "1", 108 | Relation: "member", 109 | Subject: warrant.Subject{ 110 | ObjectType: "user", 111 | ObjectId: "1", 112 | }, 113 | }) 114 | 115 | // Check access 116 | isAuthorized, err := warrant.Check(&warrant.WarrantCheckParams{ 117 | Object: warrant.Object{ 118 | ObjectType: "tenant", 119 | ObjectId: "1", 120 | }, 121 | Relation: "member", 122 | Subject: warrant.Subject{ 123 | ObjectType: "user", 124 | ObjectId: "1", 125 | }, 126 | }) 127 | ``` 128 | 129 | 130 | We’ve used a random API key in these code examples. Replace it with your 131 | [actual publishable API keys](https://app.warrant.dev) to 132 | test this code through your own Warrant account. 133 | 134 | For more information on how to use the Warrant API, please refer to the 135 | [Warrant API reference](https://docs.warrant.dev). 136 | 137 | Note that we may release new [minor and patch](https://semver.org/) versions of this library with small but backwards-incompatible fixes to the type declarations. These changes will not affect Warrant itself. 138 | 139 | ## Warrant Documentation 140 | 141 | - [Warrant Docs](https://docs.warrant.dev/) 142 | -------------------------------------------------------------------------------- /apiclient.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | ) 10 | 11 | const ( 12 | ClientVersion string = "6.1.1" 13 | ) 14 | 15 | type ApiClient struct { 16 | HttpClient *http.Client 17 | Config ClientConfig 18 | } 19 | 20 | func NewApiClient(config ClientConfig) *ApiClient { 21 | httpClient := config.HttpClient 22 | if httpClient == nil { 23 | httpClient = http.DefaultClient 24 | } 25 | 26 | return &ApiClient{ 27 | HttpClient: httpClient, 28 | Config: config, 29 | } 30 | } 31 | 32 | func (client ApiClient) MakeRequest(method string, path string, payload interface{}, options *RequestOptions) (*http.Response, error) { 33 | var request *http.Request 34 | var err error 35 | 36 | url := client.Config.ApiEndpoint + path 37 | if payload != nil { 38 | postBody, err := json.Marshal(payload) 39 | if err != nil { 40 | return nil, WrapError("Invalid request payload", err) 41 | } 42 | requestBody := bytes.NewBuffer(postBody) 43 | request, err = http.NewRequest(method, url, requestBody) 44 | if err != nil { 45 | return nil, WrapError("Unable to create request", err) 46 | } 47 | } else { 48 | request, err = http.NewRequest(method, url, nil) 49 | if err != nil { 50 | return nil, WrapError("Unable to create request", err) 51 | } 52 | } 53 | 54 | if client.Config.ApiKey != "" { 55 | request.Header.Add("Authorization", fmt.Sprintf("ApiKey %s", client.Config.ApiKey)) 56 | } 57 | if options != nil && options.WarrantToken != "" { 58 | request.Header.Add("Warrant-Token", options.WarrantToken) 59 | } 60 | request.Header.Add("User-Agent", fmt.Sprintf("warrant-go/%s", ClientVersion)) 61 | 62 | resp, err := client.HttpClient.Do(request) 63 | if err != nil { 64 | return nil, WrapError("Error making request", err) 65 | } 66 | respStatus := resp.StatusCode 67 | if respStatus < 200 || respStatus >= 400 { 68 | msg, err := io.ReadAll(resp.Body) 69 | errMsg := "" 70 | if err == nil { 71 | errMsg = string(msg) 72 | } 73 | return nil, Error{ 74 | Message: fmt.Sprintf("HTTP %d %s", respStatus, errMsg), 75 | } 76 | } 77 | 78 | return resp, nil 79 | } 80 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "net/url" 9 | 10 | "github.com/google/go-querystring/query" 11 | ) 12 | 13 | type WarrantClient struct { 14 | apiClient *ApiClient 15 | } 16 | 17 | func NewClient(config ClientConfig) WarrantClient { 18 | return WarrantClient{ 19 | apiClient: &ApiClient{ 20 | HttpClient: http.DefaultClient, 21 | Config: config, 22 | }, 23 | } 24 | } 25 | 26 | func (c WarrantClient) Create(params *WarrantParams) (*Warrant, error) { 27 | resp, err := c.apiClient.MakeRequest("POST", "/v2/warrants", params, &RequestOptions{}) 28 | if err != nil { 29 | return nil, err 30 | } 31 | body, err := io.ReadAll(resp.Body) 32 | if err != nil { 33 | return nil, WrapError("Error reading response", err) 34 | } 35 | defer resp.Body.Close() 36 | var createdWarrant Warrant 37 | err = json.Unmarshal([]byte(body), &createdWarrant) 38 | if err != nil { 39 | return nil, WrapError("Invalid response from server", err) 40 | } 41 | warrantToken := resp.Header.Get("Warrant-Token") 42 | createdWarrant.WarrantToken = warrantToken 43 | return &createdWarrant, nil 44 | } 45 | 46 | func Create(params *WarrantParams) (*Warrant, error) { 47 | return getClient().Create(params) 48 | } 49 | 50 | func (c WarrantClient) BatchCreate(params []WarrantParams) ([]Warrant, error) { 51 | resp, err := c.apiClient.MakeRequest("POST", "/v2/warrants", params, &RequestOptions{}) 52 | if err != nil { 53 | return nil, err 54 | } 55 | body, err := io.ReadAll(resp.Body) 56 | if err != nil { 57 | return nil, WrapError("Error reading response", err) 58 | } 59 | defer resp.Body.Close() 60 | var createdWarrants []Warrant 61 | err = json.Unmarshal([]byte(body), &createdWarrants) 62 | if err != nil { 63 | return nil, WrapError("Invalid response from server", err) 64 | } 65 | warrantToken := resp.Header.Get("Warrant-Token") 66 | for i := range createdWarrants { 67 | createdWarrants[i].WarrantToken = warrantToken 68 | } 69 | return createdWarrants, nil 70 | } 71 | 72 | func BatchCreate(params []WarrantParams) ([]Warrant, error) { 73 | return getClient().BatchCreate(params) 74 | } 75 | 76 | func (c WarrantClient) Delete(params *WarrantParams) (string, error) { 77 | resp, err := c.apiClient.MakeRequest("DELETE", "/v2/warrants", params, &RequestOptions{}) 78 | if err != nil { 79 | return "", err 80 | } 81 | defer resp.Body.Close() 82 | warrantToken := resp.Header.Get("Warrant-Token") 83 | return warrantToken, nil 84 | } 85 | 86 | func Delete(params *WarrantParams) (string, error) { 87 | return getClient().Delete(params) 88 | } 89 | 90 | func (c WarrantClient) BatchDelete(params []WarrantParams) (string, error) { 91 | resp, err := c.apiClient.MakeRequest("DELETE", "/v2/warrants", params, &RequestOptions{}) 92 | if err != nil { 93 | return "", err 94 | } 95 | defer resp.Body.Close() 96 | warrantToken := resp.Header.Get("Warrant-Token") 97 | return warrantToken, nil 98 | } 99 | 100 | func BatchDelete(params []WarrantParams) (string, error) { 101 | return getClient().BatchDelete(params) 102 | } 103 | 104 | func (c WarrantClient) ListWarrants(listParams *ListWarrantParams) (ListResponse[Warrant], error) { 105 | if listParams == nil { 106 | listParams = &ListWarrantParams{} 107 | } 108 | var warrantsListResponse ListResponse[Warrant] 109 | queryParams, err := query.Values(listParams) 110 | if err != nil { 111 | return warrantsListResponse, WrapError("Error parsing ListWarrantParams", err) 112 | } 113 | 114 | resp, err := c.apiClient.MakeRequest("GET", fmt.Sprintf("/v2/warrants?%s", queryParams.Encode()), warrantsListResponse, &listParams.RequestOptions) 115 | if err != nil { 116 | return warrantsListResponse, err 117 | } 118 | body, err := io.ReadAll(resp.Body) 119 | if err != nil { 120 | return warrantsListResponse, WrapError("Error reading response", err) 121 | } 122 | defer resp.Body.Close() 123 | err = json.Unmarshal([]byte(body), &warrantsListResponse) 124 | if err != nil { 125 | return warrantsListResponse, WrapError("Invalid response from server", err) 126 | } 127 | return warrantsListResponse, nil 128 | } 129 | 130 | func ListWarrants(listParams *ListWarrantParams) (ListResponse[Warrant], error) { 131 | return getClient().ListWarrants(listParams) 132 | } 133 | 134 | func (c WarrantClient) Query(queryString string, params *QueryParams) (ListResponse[QueryResult], error) { 135 | if params == nil { 136 | params = &QueryParams{} 137 | } 138 | var queryResponse ListResponse[QueryResult] 139 | queryParams, err := query.Values(params) 140 | if err != nil { 141 | return queryResponse, WrapError("Could not parse params", err) 142 | } 143 | 144 | resp, err := c.apiClient.MakeRequest("GET", fmt.Sprintf("/v2/query?q=%s&%s", url.QueryEscape(queryString), queryParams.Encode()), queryResponse, ¶ms.RequestOptions) 145 | if err != nil { 146 | return queryResponse, err 147 | } 148 | body, err := io.ReadAll(resp.Body) 149 | if err != nil { 150 | return queryResponse, WrapError("Error reading response", err) 151 | } 152 | defer resp.Body.Close() 153 | err = json.Unmarshal([]byte(body), &queryResponse) 154 | if err != nil { 155 | return queryResponse, WrapError("Invalid response from server", err) 156 | } 157 | return queryResponse, nil 158 | } 159 | 160 | func Query(queryString string, params *QueryParams) (ListResponse[QueryResult], error) { 161 | return getClient().Query(queryString, params) 162 | } 163 | 164 | func (c WarrantClient) Check(params *WarrantCheckParams) (bool, error) { 165 | if params == nil { 166 | params = &WarrantCheckParams{} 167 | } 168 | accessCheckRequest := AccessCheckRequest{ 169 | RequestOptions: params.RequestOptions, 170 | Warrants: []WarrantCheck{params.WarrantCheck}, 171 | Debug: params.Debug, 172 | } 173 | 174 | checkResult, err := c.makeAuthorizeRequest(&accessCheckRequest) 175 | if err != nil { 176 | return false, err 177 | } 178 | 179 | if checkResult.Result == "Authorized" { 180 | return true, nil 181 | } else { 182 | return false, nil 183 | } 184 | } 185 | 186 | func Check(params *WarrantCheckParams) (bool, error) { 187 | return getClient().Check(params) 188 | } 189 | 190 | func (c WarrantClient) CheckMany(params *WarrantCheckManyParams) (bool, error) { 191 | if params == nil { 192 | params = &WarrantCheckManyParams{} 193 | } 194 | warrants := make([]WarrantCheck, 0) 195 | for _, warrantCheck := range params.Warrants { 196 | warrants = append(warrants, warrantCheck) 197 | } 198 | 199 | accessCheckRequest := AccessCheckRequest{ 200 | RequestOptions: params.RequestOptions, 201 | Op: params.Op, 202 | Warrants: warrants, 203 | Debug: params.Debug, 204 | } 205 | 206 | checkResult, err := c.makeAuthorizeRequest(&accessCheckRequest) 207 | if err != nil { 208 | return false, err 209 | } 210 | 211 | if checkResult.Result == "Authorized" { 212 | return true, nil 213 | } else { 214 | return false, nil 215 | } 216 | } 217 | 218 | func CheckMany(params *WarrantCheckManyParams) (bool, error) { 219 | return getClient().CheckMany(params) 220 | } 221 | 222 | func (c WarrantClient) CheckUserHasPermission(params *PermissionCheckParams) (bool, error) { 223 | if params == nil { 224 | params = &PermissionCheckParams{} 225 | } 226 | return c.Check(&WarrantCheckParams{ 227 | RequestOptions: params.RequestOptions, 228 | WarrantCheck: WarrantCheck{ 229 | Object: Object{ 230 | ObjectType: ObjectTypePermission, 231 | ObjectId: params.PermissionId, 232 | }, 233 | Relation: "member", 234 | Subject: Subject{ 235 | ObjectType: ObjectTypeUser, 236 | ObjectId: params.UserId, 237 | }, 238 | Context: params.Context, 239 | }, 240 | Debug: params.Debug, 241 | }) 242 | } 243 | 244 | func CheckUserHasPermission(params *PermissionCheckParams) (bool, error) { 245 | return getClient().CheckUserHasPermission(params) 246 | } 247 | 248 | func (c WarrantClient) CheckUserHasRole(params *RoleCheckParams) (bool, error) { 249 | if params == nil { 250 | params = &RoleCheckParams{} 251 | } 252 | return c.Check(&WarrantCheckParams{ 253 | RequestOptions: params.RequestOptions, 254 | WarrantCheck: WarrantCheck{ 255 | Object: Object{ 256 | ObjectType: ObjectTypeRole, 257 | ObjectId: params.RoleId, 258 | }, 259 | Relation: "member", 260 | Subject: Subject{ 261 | ObjectType: ObjectTypeUser, 262 | ObjectId: params.UserId, 263 | }, 264 | Context: params.Context, 265 | }, 266 | Debug: params.Debug, 267 | }) 268 | } 269 | 270 | func CheckUserHasRole(params *RoleCheckParams) (bool, error) { 271 | return getClient().CheckUserHasRole(params) 272 | } 273 | 274 | func (c WarrantClient) CheckHasFeature(params *FeatureCheckParams) (bool, error) { 275 | if params == nil { 276 | params = &FeatureCheckParams{} 277 | } 278 | return c.Check(&WarrantCheckParams{ 279 | RequestOptions: params.RequestOptions, 280 | WarrantCheck: WarrantCheck{ 281 | Object: Object{ 282 | ObjectType: ObjectTypeFeature, 283 | ObjectId: params.FeatureId, 284 | }, 285 | Relation: "member", 286 | Subject: params.Subject, 287 | Context: params.Context, 288 | }, 289 | Debug: params.Debug, 290 | }) 291 | } 292 | 293 | func CheckHasFeature(params *FeatureCheckParams) (bool, error) { 294 | return getClient().CheckHasFeature(params) 295 | } 296 | 297 | func (c WarrantClient) makeAuthorizeRequest(params *AccessCheckRequest) (*WarrantCheckResult, error) { 298 | resp, err := c.apiClient.MakeRequest("POST", "/v2/check", params, ¶ms.RequestOptions) 299 | if err != nil { 300 | return nil, err 301 | } 302 | 303 | body, err := io.ReadAll(resp.Body) 304 | if err != nil { 305 | return nil, WrapError("Error reading response", err) 306 | } 307 | defer resp.Body.Close() 308 | var result WarrantCheckResult 309 | err = json.Unmarshal([]byte(body), &result) 310 | if err != nil { 311 | return nil, WrapError("Invalid response from server", err) 312 | } 313 | return &result, nil 314 | } 315 | 316 | func getClient() WarrantClient { 317 | config := ClientConfig{ 318 | ApiKey: ApiKey, 319 | ApiEndpoint: ApiEndpoint, 320 | AuthorizeEndpoint: AuthorizeEndpoint, 321 | SelfServiceDashEndpoint: SelfServiceDashEndpoint, 322 | HttpClient: HttpClient, 323 | } 324 | 325 | return WarrantClient{ 326 | &ApiClient{ 327 | HttpClient: HttpClient, 328 | Config: config, 329 | }, 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | import "net/http" 4 | 5 | var ApiKey string 6 | var ApiEndpoint string = "https://api.warrant.dev" 7 | var AuthorizeEndpoint string = "https://api.warrant.dev" 8 | var SelfServiceDashEndpoint string = "https://self-serve.warrant.dev" 9 | var HttpClient *http.Client = http.DefaultClient 10 | 11 | type ClientConfig struct { 12 | ApiKey string 13 | ApiEndpoint string 14 | AuthorizeEndpoint string 15 | SelfServiceDashEndpoint string 16 | HttpClient *http.Client 17 | } 18 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | import "fmt" 4 | 5 | type Error struct { 6 | Message string `json:"message"` 7 | WrappedError error `json:"-"` 8 | } 9 | 10 | func (err Error) Error() string { 11 | if err.WrappedError != nil { 12 | return fmt.Sprintf("Warrant error: %s %s", err.Message, err.WrappedError.Error()) 13 | } 14 | return fmt.Sprintf("Warrant error: %s", err.Message) 15 | } 16 | 17 | func WrapError(message string, err error) Error { 18 | return Error{ 19 | Message: message, 20 | WrappedError: err, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/live_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | "github.com/warrant-dev/warrant-go/v6" 9 | "github.com/warrant-dev/warrant-go/v6/feature" 10 | "github.com/warrant-dev/warrant-go/v6/object" 11 | "github.com/warrant-dev/warrant-go/v6/objecttype" 12 | "github.com/warrant-dev/warrant-go/v6/permission" 13 | "github.com/warrant-dev/warrant-go/v6/pricingtier" 14 | "github.com/warrant-dev/warrant-go/v6/role" 15 | "github.com/warrant-dev/warrant-go/v6/session" 16 | "github.com/warrant-dev/warrant-go/v6/tenant" 17 | "github.com/warrant-dev/warrant-go/v6/user" 18 | ) 19 | 20 | func setup() { 21 | warrant.ApiKey = "" 22 | warrant.ApiEndpoint = "https://api.warrant.dev" 23 | warrant.AuthorizeEndpoint = "https://api.warrant.dev" 24 | } 25 | 26 | func TestCrudUsers(t *testing.T) { 27 | setup() 28 | assert := assert.New(t) 29 | 30 | user1, err := user.Create(&warrant.UserParams{}) 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | assert.NotNil(user1.UserId) 35 | assert.Nil(user1.Meta) 36 | 37 | user2, err := user.Create(&warrant.UserParams{ 38 | UserId: "some_id", 39 | Meta: map[string]interface{}{ 40 | "email": "test@email.com", 41 | }, 42 | }) 43 | if err != nil { 44 | t.Fatal(err) 45 | } 46 | fetchUserParams := &warrant.UserParams{} 47 | fetchUserParams.SetWarrantToken("latest") 48 | refetchedUser, err := user.Get(user2.UserId, fetchUserParams) 49 | if err != nil { 50 | t.Fatal(err) 51 | } 52 | assert.Equal(user2.UserId, refetchedUser.UserId) 53 | assert.Equal(user2.Meta, refetchedUser.Meta) 54 | 55 | user2, err = user.Update("some_id", &warrant.UserParams{ 56 | Meta: map[string]interface{}{ 57 | "email": "updated@email.com", 58 | }, 59 | }) 60 | if err != nil { 61 | t.Fatal(err) 62 | } 63 | refetchedUser, err = user.Get("some_id", fetchUserParams) 64 | if err != nil { 65 | t.Fatal(err) 66 | } 67 | assert.Equal("some_id", refetchedUser.UserId) 68 | assert.Equal(map[string]interface{}{"email": "updated@email.com"}, refetchedUser.Meta) 69 | 70 | usersList, err := user.ListUsers(&warrant.ListUserParams{ 71 | ListParams: warrant.ListParams{ 72 | RequestOptions: warrant.RequestOptions{ 73 | WarrantToken: "latest", 74 | }, 75 | Limit: 10, 76 | }, 77 | }) 78 | if err != nil { 79 | t.Fatal(err) 80 | } 81 | assert.Equal(2, len(usersList.Results)) 82 | 83 | warrantToken, err := user.Delete(user1.UserId) 84 | if err != nil { 85 | t.Fatal(err) 86 | } 87 | assert.NotNil(warrantToken) 88 | warrantToken, err = user.Delete(user2.UserId) 89 | if err != nil { 90 | t.Fatal(err) 91 | } 92 | usersList, err = user.ListUsers(&warrant.ListUserParams{ 93 | ListParams: warrant.ListParams{ 94 | RequestOptions: warrant.RequestOptions{ 95 | WarrantToken: "latest", 96 | }, 97 | Limit: 10, 98 | }, 99 | }) 100 | if err != nil { 101 | t.Fatal(err) 102 | } 103 | assert.Equal(0, len(usersList.Results)) 104 | } 105 | 106 | func TestCrudTenants(t *testing.T) { 107 | setup() 108 | assert := assert.New(t) 109 | 110 | tenant1, err := tenant.Create(&warrant.TenantParams{}) 111 | if err != nil { 112 | t.Fatal(err) 113 | } 114 | assert.NotNil(tenant1.TenantId) 115 | assert.Nil(tenant1.Meta) 116 | 117 | tenant2, err := tenant.Create(&warrant.TenantParams{ 118 | TenantId: "some_tenant_id", 119 | Meta: map[string]interface{}{ 120 | "name": "new_name", 121 | }, 122 | }) 123 | if err != nil { 124 | t.Fatal(err) 125 | } 126 | fetchTenantParams := &warrant.TenantParams{} 127 | fetchTenantParams.SetWarrantToken("latest") 128 | refetchedTenant, err := tenant.Get(tenant2.TenantId, fetchTenantParams) 129 | if err != nil { 130 | t.Fatal(err) 131 | } 132 | assert.Equal(tenant2.TenantId, refetchedTenant.TenantId) 133 | assert.Equal(tenant2.Meta, refetchedTenant.Meta) 134 | 135 | tenant2, err = tenant.Update("some_tenant_id", &warrant.TenantParams{ 136 | Meta: map[string]interface{}{ 137 | "name": "updated_name", 138 | }, 139 | }) 140 | if err != nil { 141 | t.Fatal(err) 142 | } 143 | refetchedTenant, err = tenant.Get("some_tenant_id", fetchTenantParams) 144 | if err != nil { 145 | t.Fatal(err) 146 | } 147 | assert.Equal("some_tenant_id", refetchedTenant.TenantId) 148 | assert.Equal(map[string]interface{}{"name": "updated_name"}, refetchedTenant.Meta) 149 | 150 | tenantsList, err := tenant.ListTenants(&warrant.ListTenantParams{ 151 | ListParams: warrant.ListParams{ 152 | RequestOptions: warrant.RequestOptions{ 153 | WarrantToken: "latest", 154 | }, 155 | Limit: 10, 156 | }, 157 | }) 158 | if err != nil { 159 | t.Fatal(err) 160 | } 161 | assert.Equal(2, len(tenantsList.Results)) 162 | 163 | warrantToken, err := tenant.Delete(tenant1.TenantId) 164 | if err != nil { 165 | t.Fatal(err) 166 | } 167 | assert.NotNil(warrantToken) 168 | warrantToken, err = tenant.Delete(tenant2.TenantId) 169 | if err != nil { 170 | t.Fatal(err) 171 | } 172 | assert.NotNil(warrantToken) 173 | tenantsList, err = tenant.ListTenants(&warrant.ListTenantParams{ 174 | ListParams: warrant.ListParams{ 175 | RequestOptions: warrant.RequestOptions{ 176 | WarrantToken: "latest", 177 | }, 178 | Limit: 10, 179 | }, 180 | }) 181 | if err != nil { 182 | t.Fatal(err) 183 | } 184 | assert.Equal(0, len(tenantsList.Results)) 185 | } 186 | 187 | func TestCrudRoles(t *testing.T) { 188 | setup() 189 | assert := assert.New(t) 190 | 191 | adminRole, err := role.Create(&warrant.RoleParams{ 192 | RoleId: "admin", 193 | Meta: map[string]interface{}{ 194 | "name": "Admin", 195 | "description": "The admin role", 196 | }, 197 | }) 198 | if err != nil { 199 | t.Fatal(err) 200 | } 201 | assert.Equal("admin", adminRole.RoleId) 202 | assert.Equal(map[string]interface{}{ 203 | "name": "Admin", 204 | "description": "The admin role", 205 | }, adminRole.Meta) 206 | 207 | viewerRole, err := role.Create(&warrant.RoleParams{ 208 | RoleId: "viewer", 209 | Meta: map[string]interface{}{ 210 | "name": "Viewer", 211 | "description": "The viewer role", 212 | }, 213 | }) 214 | if err != nil { 215 | t.Fatal(err) 216 | } 217 | fetchRoleParams := &warrant.RoleParams{} 218 | fetchRoleParams.SetWarrantToken("latest") 219 | refetchedRole, err := role.Get(viewerRole.RoleId, fetchRoleParams) 220 | if err != nil { 221 | t.Fatal(err) 222 | } 223 | assert.Equal(viewerRole.RoleId, refetchedRole.RoleId) 224 | assert.Equal(viewerRole.Meta, refetchedRole.Meta) 225 | 226 | viewerRole, err = role.Update("viewer", &warrant.RoleParams{ 227 | Meta: map[string]interface{}{ 228 | "name": "Viewer Updated", 229 | "description": "Updated desc", 230 | }, 231 | }) 232 | if err != nil { 233 | t.Fatal(err) 234 | } 235 | refetchedRole, err = role.Get(viewerRole.RoleId, fetchRoleParams) 236 | if err != nil { 237 | t.Fatal(err) 238 | } 239 | assert.Equal("viewer", refetchedRole.RoleId) 240 | assert.Equal(map[string]interface{}{ 241 | "name": "Viewer Updated", 242 | "description": "Updated desc", 243 | }, refetchedRole.Meta) 244 | 245 | rolesList, err := role.ListRoles(&warrant.ListRoleParams{ 246 | ListParams: warrant.ListParams{ 247 | RequestOptions: warrant.RequestOptions{ 248 | WarrantToken: "latest", 249 | }, 250 | Limit: 10, 251 | }, 252 | }) 253 | if err != nil { 254 | t.Fatal(err) 255 | } 256 | assert.Equal(2, len(rolesList.Results)) 257 | 258 | warrantToken, err := role.Delete(adminRole.RoleId) 259 | if err != nil { 260 | t.Fatal(err) 261 | } 262 | assert.NotNil(warrantToken) 263 | warrantToken, err = role.Delete(viewerRole.RoleId) 264 | if err != nil { 265 | t.Fatal(err) 266 | } 267 | assert.NotNil(warrantToken) 268 | rolesList, err = role.ListRoles(&warrant.ListRoleParams{ 269 | ListParams: warrant.ListParams{ 270 | RequestOptions: warrant.RequestOptions{ 271 | WarrantToken: "latest", 272 | }, 273 | Limit: 10, 274 | }, 275 | }) 276 | if err != nil { 277 | t.Fatal(err) 278 | } 279 | assert.Equal(0, len(rolesList.Results)) 280 | } 281 | 282 | func TestCrudPermissions(t *testing.T) { 283 | setup() 284 | assert := assert.New(t) 285 | 286 | permission1, err := permission.Create(&warrant.PermissionParams{ 287 | PermissionId: "perm1", 288 | Meta: map[string]interface{}{ 289 | "name": "Permission 1", 290 | "description": "Permission with id 1", 291 | }, 292 | }) 293 | if err != nil { 294 | t.Fatal(err) 295 | } 296 | assert.Equal("perm1", permission1.PermissionId) 297 | assert.Equal(map[string]interface{}{ 298 | "name": "Permission 1", 299 | "description": "Permission with id 1", 300 | }, permission1.Meta) 301 | 302 | permission2, err := permission.Create(&warrant.PermissionParams{ 303 | PermissionId: "perm2", 304 | Meta: map[string]interface{}{ 305 | "name": "Permission 2", 306 | "description": "Permission with id 2", 307 | }, 308 | }) 309 | if err != nil { 310 | t.Fatal(err) 311 | } 312 | assert.Equal("perm2", permission2.PermissionId) 313 | assert.Equal(map[string]interface{}{ 314 | "name": "Permission 2", 315 | "description": "Permission with id 2", 316 | }, permission2.Meta) 317 | 318 | permission2, err = permission.Update("perm2", &warrant.PermissionParams{ 319 | Meta: map[string]interface{}{ 320 | "name": "Permission 2 Updated", 321 | "description": "Updated desc", 322 | }, 323 | }) 324 | if err != nil { 325 | t.Fatal(err) 326 | } 327 | fetchPermissionParams := &warrant.PermissionParams{} 328 | fetchPermissionParams.SetWarrantToken("latest") 329 | refetchedPermission, err := permission.Get("perm2", fetchPermissionParams) 330 | if err != nil { 331 | t.Fatal(err) 332 | } 333 | assert.Equal("perm2", refetchedPermission.PermissionId) 334 | assert.Equal(map[string]interface{}{ 335 | "name": "Permission 2 Updated", 336 | "description": "Updated desc", 337 | }, refetchedPermission.Meta) 338 | 339 | permissionsList, err := permission.ListPermissions(&warrant.ListPermissionParams{ 340 | ListParams: warrant.ListParams{ 341 | RequestOptions: warrant.RequestOptions{ 342 | WarrantToken: "latest", 343 | }, 344 | Limit: 10, 345 | }, 346 | }) 347 | if err != nil { 348 | t.Fatal(err) 349 | } 350 | assert.Equal(2, len(permissionsList.Results)) 351 | 352 | warrantToken, err := permission.Delete(permission1.PermissionId) 353 | if err != nil { 354 | t.Fatal(err) 355 | } 356 | assert.NotNil(warrantToken) 357 | warrantToken, err = permission.Delete(permission2.PermissionId) 358 | if err != nil { 359 | t.Fatal(err) 360 | } 361 | assert.NotNil(warrantToken) 362 | permissionsList, err = permission.ListPermissions(&warrant.ListPermissionParams{ 363 | ListParams: warrant.ListParams{ 364 | RequestOptions: warrant.RequestOptions{ 365 | WarrantToken: "latest", 366 | }, 367 | Limit: 10, 368 | }, 369 | }) 370 | if err != nil { 371 | t.Fatal(err) 372 | } 373 | assert.Equal(0, len(permissionsList.Results)) 374 | } 375 | 376 | func TestCrudFeatures(t *testing.T) { 377 | setup() 378 | assert := assert.New(t) 379 | 380 | feature1, err := feature.Create(&warrant.FeatureParams{ 381 | FeatureId: "new-feature", 382 | }) 383 | if err != nil { 384 | t.Fatal(err) 385 | } 386 | assert.Equal("new-feature", feature1.FeatureId) 387 | 388 | feature2, err := feature.Create(&warrant.FeatureParams{ 389 | FeatureId: "feature-2", 390 | Meta: map[string]interface{}{ 391 | "name": "Feature 2", 392 | }, 393 | }) 394 | if err != nil { 395 | t.Fatal(err) 396 | } 397 | fetchFeatureParams := &warrant.FeatureParams{} 398 | fetchFeatureParams.SetWarrantToken("latest") 399 | refetchedFeature, err := feature.Get(feature2.FeatureId, fetchFeatureParams) 400 | if err != nil { 401 | t.Fatal(err) 402 | } 403 | assert.Equal(feature2.FeatureId, refetchedFeature.FeatureId) 404 | assert.Equal(feature2.Meta, refetchedFeature.Meta) 405 | 406 | feature2, err = feature.Update(feature2.FeatureId, &warrant.FeatureParams{ 407 | Meta: map[string]interface{}{ 408 | "name": "Updated Feature 2", 409 | }, 410 | }) 411 | if err != nil { 412 | t.Fatal(err) 413 | } 414 | refetchedFeature, err = feature.Get(feature2.FeatureId, fetchFeatureParams) 415 | if err != nil { 416 | t.Fatal(err) 417 | } 418 | assert.Equal("feature-2", refetchedFeature.FeatureId) 419 | assert.Equal(map[string]interface{}{"name": "Updated Feature 2"}, refetchedFeature.Meta) 420 | 421 | featuresList, err := feature.ListFeatures(&warrant.ListFeatureParams{ 422 | ListParams: warrant.ListParams{ 423 | RequestOptions: warrant.RequestOptions{ 424 | WarrantToken: "latest", 425 | }, 426 | Limit: 10, 427 | }, 428 | }) 429 | if err != nil { 430 | t.Fatal(err) 431 | } 432 | assert.Equal(2, len(featuresList.Results)) 433 | 434 | warrantToken, err := feature.Delete(feature1.FeatureId) 435 | if err != nil { 436 | t.Fatal(err) 437 | } 438 | assert.NotNil(warrantToken) 439 | warrantToken, err = feature.Delete(feature2.FeatureId) 440 | if err != nil { 441 | t.Fatal(err) 442 | } 443 | assert.NotNil(warrantToken) 444 | featuresList, err = feature.ListFeatures(&warrant.ListFeatureParams{ 445 | ListParams: warrant.ListParams{ 446 | RequestOptions: warrant.RequestOptions{ 447 | WarrantToken: "latest", 448 | }, 449 | Limit: 10, 450 | }, 451 | }) 452 | if err != nil { 453 | t.Fatal(err) 454 | } 455 | assert.Equal(0, len(featuresList.Results)) 456 | } 457 | 458 | func TestCrudPricingTiers(t *testing.T) { 459 | setup() 460 | assert := assert.New(t) 461 | 462 | tier1, err := pricingtier.Create(&warrant.PricingTierParams{ 463 | PricingTierId: "new-tier1", 464 | }) 465 | if err != nil { 466 | t.Fatal(err) 467 | } 468 | assert.Equal("new-tier1", tier1.PricingTierId) 469 | 470 | tier2, err := pricingtier.Create(&warrant.PricingTierParams{ 471 | PricingTierId: "tier-2", 472 | Meta: map[string]interface{}{ 473 | "name": "Tier 2", 474 | }, 475 | }) 476 | if err != nil { 477 | t.Fatal(err) 478 | } 479 | fetchTierParams := &warrant.PricingTierParams{} 480 | fetchTierParams.SetWarrantToken("latest") 481 | refetchedTier, err := pricingtier.Get(tier2.PricingTierId, fetchTierParams) 482 | if err != nil { 483 | t.Fatal(err) 484 | } 485 | assert.Equal(tier2.PricingTierId, refetchedTier.PricingTierId) 486 | assert.Equal(tier2.Meta, refetchedTier.Meta) 487 | 488 | tier2, err = pricingtier.Update(tier2.PricingTierId, &warrant.PricingTierParams{ 489 | Meta: map[string]interface{}{ 490 | "name": "Updated Tier 2", 491 | }, 492 | }) 493 | if err != nil { 494 | t.Fatal(err) 495 | } 496 | assert.Equal("tier-2", tier2.PricingTierId) 497 | assert.Equal(map[string]interface{}{"name": "Updated Tier 2"}, tier2.Meta) 498 | 499 | tiersList, err := pricingtier.ListPricingTiers(&warrant.ListPricingTierParams{ 500 | ListParams: warrant.ListParams{ 501 | RequestOptions: warrant.RequestOptions{ 502 | WarrantToken: "latest", 503 | }, 504 | Limit: 10, 505 | }, 506 | }) 507 | if err != nil { 508 | t.Fatal(err) 509 | } 510 | assert.Equal(2, len(tiersList.Results)) 511 | 512 | warrantToken, err := pricingtier.Delete(tier1.PricingTierId) 513 | if err != nil { 514 | t.Fatal(err) 515 | } 516 | assert.NotNil(warrantToken) 517 | warrantToken, err = pricingtier.Delete(tier2.PricingTierId) 518 | if err != nil { 519 | t.Fatal(err) 520 | } 521 | assert.NotNil(warrantToken) 522 | tiersList, err = pricingtier.ListPricingTiers(&warrant.ListPricingTierParams{ 523 | ListParams: warrant.ListParams{ 524 | RequestOptions: warrant.RequestOptions{ 525 | WarrantToken: "latest", 526 | }, 527 | Limit: 10, 528 | }, 529 | }) 530 | if err != nil { 531 | t.Fatal(err) 532 | } 533 | assert.Equal(0, len(tiersList.Results)) 534 | } 535 | 536 | func TestBatchCreateUsersAndTenants(t *testing.T) { 537 | setup() 538 | assert := assert.New(t) 539 | 540 | createdUsers, err := user.BatchCreate([]warrant.UserParams{ 541 | {UserId: "user-1"}, 542 | {UserId: "user-2"}, 543 | }) 544 | if err != nil { 545 | t.Fatal(err) 546 | } 547 | assert.Equal(2, len(createdUsers)) 548 | assert.Equal("user-1", createdUsers[0].UserId) 549 | assert.Equal("user-2", createdUsers[1].UserId) 550 | 551 | createdTenants, err := tenant.BatchCreate([]warrant.TenantParams{ 552 | {TenantId: "tenant-1"}, 553 | {TenantId: "tenant-2"}, 554 | }) 555 | if err != nil { 556 | t.Fatal(err) 557 | } 558 | assert.Equal(2, len(createdTenants)) 559 | assert.Equal("tenant-1", createdTenants[0].TenantId) 560 | assert.Equal("tenant-2", createdTenants[1].TenantId) 561 | 562 | warrantToken, err := user.Delete("user-1") 563 | if err != nil { 564 | t.Fatal(err) 565 | } 566 | assert.NotNil(warrantToken) 567 | warrantToken, err = user.Delete("user-2") 568 | if err != nil { 569 | t.Fatal(err) 570 | } 571 | assert.NotNil(warrantToken) 572 | warrantToken, err = tenant.Delete("tenant-1") 573 | if err != nil { 574 | t.Fatal(err) 575 | } 576 | assert.NotNil(warrantToken) 577 | warrantToken, err = tenant.Delete("tenant-2") 578 | if err != nil { 579 | t.Fatal(err) 580 | } 581 | assert.NotNil(warrantToken) 582 | } 583 | 584 | func TestMultiTenancy(t *testing.T) { 585 | setup() 586 | assert := assert.New(t) 587 | 588 | // Create users 589 | user1, err := user.Create(&warrant.UserParams{}) 590 | if err != nil { 591 | t.Fatal(err) 592 | } 593 | user2, err := user.Create(nil) 594 | if err != nil { 595 | t.Fatal(err) 596 | } 597 | 598 | // Create tenants 599 | tenant1, err := tenant.Create(&warrant.TenantParams{ 600 | TenantId: "tenant-1", 601 | Meta: map[string]interface{}{ 602 | "name": "Tenant 1", 603 | }, 604 | }) 605 | if err != nil { 606 | t.Fatal(err) 607 | } 608 | tenant2, err := tenant.Create(&warrant.TenantParams{ 609 | TenantId: "tenant-2", 610 | Meta: map[string]interface{}{ 611 | "name": "Tenant 2", 612 | }, 613 | }) 614 | if err != nil { 615 | t.Fatal(err) 616 | } 617 | 618 | // Assign user1 -> tenant1 619 | user1TenantsList, err := tenant.ListTenantsForUser(user1.UserId, &warrant.ListTenantParams{ 620 | ListParams: warrant.ListParams{ 621 | RequestOptions: warrant.RequestOptions{ 622 | WarrantToken: "latest", 623 | }, 624 | Limit: 100, 625 | }, 626 | }) 627 | if err != nil { 628 | t.Fatal(err) 629 | } 630 | assert.Equal(0, len(user1TenantsList.Results)) 631 | tenant1UsersList, err := user.ListUsersForTenant(tenant1.TenantId, &warrant.ListUserParams{ 632 | ListParams: warrant.ListParams{ 633 | RequestOptions: warrant.RequestOptions{ 634 | WarrantToken: "latest", 635 | }, 636 | Limit: 100, 637 | }, 638 | }) 639 | if err != nil { 640 | t.Fatal(err) 641 | } 642 | assert.Equal(0, len(tenant1UsersList.Results)) 643 | 644 | _, err = user.AssignUserToTenant(user1.UserId, tenant1.TenantId, "member") 645 | if err != nil { 646 | t.Fatal(err) 647 | } 648 | 649 | user1TenantsList, err = tenant.ListTenantsForUser(user1.UserId, &warrant.ListTenantParams{ 650 | ListParams: warrant.ListParams{ 651 | RequestOptions: warrant.RequestOptions{ 652 | WarrantToken: "latest", 653 | }, 654 | Limit: 100, 655 | }, 656 | }) 657 | if err != nil { 658 | t.Fatal(err) 659 | } 660 | assert.Equal(1, len(user1TenantsList.Results)) 661 | assert.Equal("tenant-1", user1TenantsList.Results[0].TenantId) 662 | tenant1UsersList, err = user.ListUsersForTenant(tenant1.TenantId, &warrant.ListUserParams{ 663 | ListParams: warrant.ListParams{ 664 | RequestOptions: warrant.RequestOptions{ 665 | WarrantToken: "latest", 666 | }, 667 | Limit: 100, 668 | }, 669 | }) 670 | if err != nil { 671 | t.Fatal(err) 672 | } 673 | assert.Equal(1, len(tenant1UsersList.Results)) 674 | assert.Equal(user1.UserId, tenant1UsersList.Results[0].UserId) 675 | 676 | warrantToken, err := user.RemoveUserFromTenant(user1.UserId, tenant1.TenantId, "member") 677 | if err != nil { 678 | t.Fatal(err) 679 | } 680 | assert.NotNil(warrantToken) 681 | 682 | // Clean up 683 | warrantToken, err = user.Delete(user1.UserId) 684 | if err != nil { 685 | t.Fatal(err) 686 | } 687 | assert.NotNil(warrantToken) 688 | warrantToken, err = user.Delete(user2.UserId) 689 | if err != nil { 690 | t.Fatal(err) 691 | } 692 | assert.NotNil(warrantToken) 693 | warrantToken, err = tenant.Delete(tenant1.TenantId) 694 | if err != nil { 695 | t.Fatal(err) 696 | } 697 | assert.NotNil(warrantToken) 698 | warrantToken, err = tenant.Delete(tenant2.TenantId) 699 | if err != nil { 700 | t.Fatal(err) 701 | } 702 | assert.NotNil(warrantToken) 703 | } 704 | 705 | func TestRBAC(t *testing.T) { 706 | setup() 707 | assert := assert.New(t) 708 | 709 | // Create users 710 | adminUser, err := user.Create(&warrant.UserParams{}) 711 | if err != nil { 712 | t.Fatal(err) 713 | } 714 | viewerUser, err := user.Create(&warrant.UserParams{}) 715 | if err != nil { 716 | t.Fatal(err) 717 | } 718 | 719 | // Create roles 720 | adminRole, err := role.Create(&warrant.RoleParams{ 721 | RoleId: "administrator", 722 | Meta: map[string]interface{}{ 723 | "name": "Administrator", 724 | "description": "The admin role", 725 | }, 726 | }) 727 | if err != nil { 728 | t.Fatal(err) 729 | } 730 | viewerRole, err := role.Create(&warrant.RoleParams{ 731 | RoleId: "viewer", 732 | Meta: map[string]interface{}{ 733 | "name": "Viewer", 734 | "description": "The viewer role", 735 | }, 736 | }) 737 | if err != nil { 738 | t.Fatal(err) 739 | } 740 | 741 | // Create permissions 742 | createPermission, err := permission.Create(&warrant.PermissionParams{ 743 | PermissionId: "create-report", 744 | Meta: map[string]interface{}{ 745 | "name": "Create Report", 746 | "description": "Permission to create reports", 747 | }, 748 | }) 749 | if err != nil { 750 | t.Fatal(err) 751 | } 752 | viewPermission, err := permission.Create(&warrant.PermissionParams{ 753 | PermissionId: "view-report", 754 | Meta: map[string]interface{}{ 755 | "name": "View Report", 756 | "description": "Permission to view reports", 757 | }, 758 | }) 759 | if err != nil { 760 | t.Fatal(err) 761 | } 762 | 763 | // Admin user tests 764 | adminUserRolesList, err := role.ListRolesForUser(adminUser.UserId, &warrant.ListRoleParams{ 765 | ListParams: warrant.ListParams{ 766 | RequestOptions: warrant.RequestOptions{ 767 | WarrantToken: "latest", 768 | }, 769 | Limit: 100, 770 | }, 771 | }) 772 | if err != nil { 773 | t.Fatal(err) 774 | } 775 | assert.Equal(0, len(adminUserRolesList.Results)) 776 | 777 | adminRolePermissionsList, err := permission.ListPermissionsForRole(adminRole.RoleId, &warrant.ListPermissionParams{ 778 | ListParams: warrant.ListParams{ 779 | RequestOptions: warrant.RequestOptions{ 780 | WarrantToken: "latest", 781 | }, 782 | Limit: 100, 783 | }, 784 | }) 785 | if err != nil { 786 | t.Fatal(err) 787 | } 788 | assert.Equal(0, len(adminRolePermissionsList.Results)) 789 | 790 | adminUserHasPermission, err := warrant.CheckUserHasPermission(&warrant.PermissionCheckParams{ 791 | RequestOptions: warrant.RequestOptions{ 792 | WarrantToken: "latest", 793 | }, 794 | PermissionId: "create-report", 795 | UserId: adminUser.UserId, 796 | }) 797 | if err != nil { 798 | t.Fatal(err) 799 | } 800 | assert.False(adminUserHasPermission) 801 | 802 | // Assign create-report permission -> admin role -> admin user 803 | _, err = permission.AssignPermissionToRole(createPermission.PermissionId, adminRole.RoleId) 804 | if err != nil { 805 | t.Fatal(err) 806 | } 807 | 808 | _, err = role.AssignRoleToUser(adminRole.RoleId, adminUser.UserId) 809 | if err != nil { 810 | t.Fatal(err) 811 | } 812 | 813 | adminRolePermissionsList, err = permission.ListPermissionsForRole(adminRole.RoleId, &warrant.ListPermissionParams{ 814 | ListParams: warrant.ListParams{ 815 | RequestOptions: warrant.RequestOptions{ 816 | WarrantToken: "latest", 817 | }, 818 | Limit: 100, 819 | }, 820 | }) 821 | if err != nil { 822 | t.Fatal(err) 823 | } 824 | assert.Equal(1, len(adminRolePermissionsList.Results)) 825 | assert.Equal("create-report", adminRolePermissionsList.Results[0].PermissionId) 826 | 827 | adminUserHasPermission, err = warrant.CheckUserHasPermission(&warrant.PermissionCheckParams{ 828 | RequestOptions: warrant.RequestOptions{ 829 | WarrantToken: "latest", 830 | }, 831 | PermissionId: "create-report", 832 | UserId: adminUser.UserId, 833 | }) 834 | if err != nil { 835 | t.Fatal(err) 836 | } 837 | assert.True(adminUserHasPermission) 838 | 839 | adminUserRolesList, err = role.ListRolesForUser(adminUser.UserId, &warrant.ListRoleParams{ 840 | ListParams: warrant.ListParams{ 841 | RequestOptions: warrant.RequestOptions{ 842 | WarrantToken: "latest", 843 | }, 844 | Limit: 100, 845 | }, 846 | }) 847 | if err != nil { 848 | t.Fatal(err) 849 | } 850 | assert.Equal(1, len(adminUserRolesList.Results)) 851 | assert.Equal("administrator", adminUserRolesList.Results[0].RoleId) 852 | 853 | // Remove create-report permission -> admin role -> admin user 854 | warrantToken, err := permission.RemovePermissionFromRole(createPermission.PermissionId, adminRole.RoleId) 855 | if err != nil { 856 | t.Fatal(err) 857 | } 858 | assert.NotNil(warrantToken) 859 | 860 | adminUserHasPermission, err = warrant.CheckUserHasPermission(&warrant.PermissionCheckParams{ 861 | RequestOptions: warrant.RequestOptions{ 862 | WarrantToken: "latest", 863 | }, 864 | PermissionId: "create-report", 865 | UserId: adminUser.UserId, 866 | }) 867 | if err != nil { 868 | t.Fatal(err) 869 | } 870 | assert.False(adminUserHasPermission) 871 | 872 | adminUserRolesList, err = role.ListRolesForUser(adminUser.UserId, &warrant.ListRoleParams{ 873 | ListParams: warrant.ListParams{ 874 | RequestOptions: warrant.RequestOptions{ 875 | WarrantToken: "latest", 876 | }, 877 | Limit: 100, 878 | }, 879 | }) 880 | if err != nil { 881 | t.Fatal(err) 882 | } 883 | assert.Equal(1, len(adminUserRolesList.Results)) 884 | 885 | warrantToken, err = role.RemoveRoleFromUser(adminRole.RoleId, adminUser.UserId) 886 | if err != nil { 887 | t.Fatal(err) 888 | } 889 | assert.NotNil(warrantToken) 890 | 891 | adminUserRolesList, err = role.ListRolesForUser(adminUser.UserId, &warrant.ListRoleParams{ 892 | ListParams: warrant.ListParams{ 893 | RequestOptions: warrant.RequestOptions{ 894 | WarrantToken: "latest", 895 | }, 896 | Limit: 100, 897 | }, 898 | }) 899 | if err != nil { 900 | t.Fatal(err) 901 | } 902 | assert.Equal(0, len(adminUserRolesList.Results)) 903 | 904 | // Viewer user tests 905 | viewerUserHasPermission, err := warrant.CheckUserHasPermission(&warrant.PermissionCheckParams{ 906 | RequestOptions: warrant.RequestOptions{ 907 | WarrantToken: "latest", 908 | }, 909 | PermissionId: "view-report", 910 | UserId: viewerUser.UserId, 911 | }) 912 | if err != nil { 913 | t.Fatal(err) 914 | } 915 | assert.False(viewerUserHasPermission) 916 | 917 | viewerUserPermissionsList, err := permission.ListPermissionsForUser(viewerUser.UserId, &warrant.ListPermissionParams{ 918 | ListParams: warrant.ListParams{ 919 | RequestOptions: warrant.RequestOptions{ 920 | WarrantToken: "latest", 921 | }, 922 | Limit: 100, 923 | }, 924 | }) 925 | if err != nil { 926 | t.Fatal(err) 927 | } 928 | assert.Equal(0, len(viewerUserPermissionsList.Results)) 929 | 930 | // Assign view-report permission -> viewer user 931 | _, err = permission.AssignPermissionToUser(viewPermission.PermissionId, viewerUser.UserId) 932 | if err != nil { 933 | t.Fatal(err) 934 | } 935 | 936 | viewerUserHasPermission, err = warrant.CheckUserHasPermission(&warrant.PermissionCheckParams{ 937 | RequestOptions: warrant.RequestOptions{ 938 | WarrantToken: "latest", 939 | }, 940 | PermissionId: "view-report", 941 | UserId: viewerUser.UserId, 942 | }) 943 | if err != nil { 944 | t.Fatal(err) 945 | } 946 | assert.True(viewerUserHasPermission) 947 | 948 | viewerUserPermissionsList, err = permission.ListPermissionsForUser(viewerUser.UserId, &warrant.ListPermissionParams{ 949 | ListParams: warrant.ListParams{ 950 | RequestOptions: warrant.RequestOptions{ 951 | WarrantToken: "latest", 952 | }, 953 | Limit: 100, 954 | }, 955 | }) 956 | if err != nil { 957 | t.Fatal(err) 958 | } 959 | assert.Equal(1, len(viewerUserPermissionsList.Results)) 960 | assert.Equal("view-report", viewerUserPermissionsList.Results[0].PermissionId) 961 | 962 | // Remove view-report permission -> viewer user 963 | warrantToken, err = permission.RemovePermissionFromUser(viewPermission.PermissionId, viewerUser.UserId) 964 | if err != nil { 965 | t.Fatal(err) 966 | } 967 | assert.NotNil(warrantToken) 968 | 969 | viewerUserHasPermission, err = warrant.CheckUserHasPermission(&warrant.PermissionCheckParams{ 970 | RequestOptions: warrant.RequestOptions{ 971 | WarrantToken: "latest", 972 | }, 973 | PermissionId: "view-report", 974 | UserId: viewerUser.UserId, 975 | }) 976 | if err != nil { 977 | t.Fatal(err) 978 | } 979 | assert.False(viewerUserHasPermission) 980 | 981 | viewerUserPermissionsList, err = permission.ListPermissionsForUser(viewerUser.UserId, &warrant.ListPermissionParams{ 982 | ListParams: warrant.ListParams{ 983 | RequestOptions: warrant.RequestOptions{ 984 | WarrantToken: "latest", 985 | }, 986 | Limit: 100, 987 | }, 988 | }) 989 | if err != nil { 990 | t.Fatal(err) 991 | } 992 | assert.Equal(0, len(viewerUserPermissionsList.Results)) 993 | 994 | // Clean up 995 | warrantToken, err = user.Delete(adminUser.UserId) 996 | if err != nil { 997 | t.Fatal(err) 998 | } 999 | assert.NotNil(warrantToken) 1000 | warrantToken, err = user.Delete(viewerUser.UserId) 1001 | if err != nil { 1002 | t.Fatal(err) 1003 | } 1004 | assert.NotNil(warrantToken) 1005 | warrantToken, err = role.Delete(adminRole.RoleId) 1006 | if err != nil { 1007 | t.Fatal(err) 1008 | } 1009 | assert.NotNil(warrantToken) 1010 | warrantToken, err = role.Delete(viewerRole.RoleId) 1011 | if err != nil { 1012 | t.Fatal(err) 1013 | } 1014 | assert.NotNil(warrantToken) 1015 | warrantToken, err = permission.Delete(createPermission.PermissionId) 1016 | if err != nil { 1017 | t.Fatal(err) 1018 | } 1019 | assert.NotNil(warrantToken) 1020 | warrantToken, err = permission.Delete(viewPermission.PermissionId) 1021 | if err != nil { 1022 | t.Fatal(err) 1023 | } 1024 | assert.NotNil(warrantToken) 1025 | } 1026 | 1027 | func TestPricingTiersAndFeaturesUsers(t *testing.T) { 1028 | setup() 1029 | assert := assert.New(t) 1030 | 1031 | // Create users 1032 | freeUser, err := user.Create(&warrant.UserParams{}) 1033 | if err != nil { 1034 | t.Fatal(err) 1035 | } 1036 | 1037 | paidUser, err := user.Create(&warrant.UserParams{}) 1038 | if err != nil { 1039 | t.Fatal(err) 1040 | } 1041 | 1042 | // Create pricing tieres 1043 | freeTier, err := pricingtier.Create(&warrant.PricingTierParams{ 1044 | PricingTierId: "free", 1045 | }) 1046 | if err != nil { 1047 | t.Fatal(err) 1048 | } 1049 | 1050 | paidTier, err := pricingtier.Create(&warrant.PricingTierParams{ 1051 | PricingTierId: "paid", 1052 | }) 1053 | if err != nil { 1054 | t.Fatal(err) 1055 | } 1056 | 1057 | // Create features 1058 | customFeature, err := feature.Create(&warrant.FeatureParams{ 1059 | FeatureId: "custom-feature", 1060 | }) 1061 | if err != nil { 1062 | t.Fatal(err) 1063 | } 1064 | 1065 | feature1, err := feature.Create(&warrant.FeatureParams{ 1066 | FeatureId: "feature-1", 1067 | }) 1068 | if err != nil { 1069 | t.Fatal(err) 1070 | } 1071 | 1072 | feature2, err := feature.Create(&warrant.FeatureParams{ 1073 | FeatureId: "feature-2", 1074 | }) 1075 | if err != nil { 1076 | t.Fatal(err) 1077 | } 1078 | 1079 | // Paid user tests 1080 | paidUserHasFeature, err := warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1081 | RequestOptions: warrant.RequestOptions{ 1082 | WarrantToken: "latest", 1083 | }, 1084 | FeatureId: "custom-feature", 1085 | Subject: warrant.Subject{ 1086 | ObjectType: warrant.ObjectTypeUser, 1087 | ObjectId: paidUser.UserId, 1088 | }, 1089 | }) 1090 | if err != nil { 1091 | t.Fatal(err) 1092 | } 1093 | assert.False(paidUserHasFeature) 1094 | 1095 | paidUserFeaturesList, err := feature.ListFeaturesForUser(paidUser.UserId, &warrant.ListFeatureParams{ 1096 | ListParams: warrant.ListParams{ 1097 | RequestOptions: warrant.RequestOptions{ 1098 | WarrantToken: "latest", 1099 | }, 1100 | Limit: 100, 1101 | }, 1102 | }) 1103 | if err != nil { 1104 | t.Fatal(err) 1105 | } 1106 | assert.Equal(0, len(paidUserFeaturesList.Results)) 1107 | 1108 | // Assign custom feature -> paid user 1109 | _, err = feature.AssignFeatureToUser(customFeature.FeatureId, paidUser.UserId) 1110 | if err != nil { 1111 | t.Fatal(err) 1112 | } 1113 | 1114 | paidUserHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1115 | RequestOptions: warrant.RequestOptions{ 1116 | WarrantToken: "latest", 1117 | }, 1118 | FeatureId: "custom-feature", 1119 | Subject: warrant.Subject{ 1120 | ObjectType: warrant.ObjectTypeUser, 1121 | ObjectId: paidUser.UserId, 1122 | }, 1123 | }) 1124 | if err != nil { 1125 | t.Fatal(err) 1126 | } 1127 | assert.True(paidUserHasFeature) 1128 | 1129 | paidUserFeaturesList, err = feature.ListFeaturesForUser(paidUser.UserId, &warrant.ListFeatureParams{ 1130 | ListParams: warrant.ListParams{ 1131 | RequestOptions: warrant.RequestOptions{ 1132 | WarrantToken: "latest", 1133 | }, 1134 | Limit: 100, 1135 | }, 1136 | }) 1137 | if err != nil { 1138 | t.Fatal(err) 1139 | } 1140 | assert.Equal(1, len(paidUserFeaturesList.Results)) 1141 | assert.Equal("custom-feature", paidUserFeaturesList.Results[0].FeatureId) 1142 | 1143 | warrantToken, err := feature.RemoveFeatureFromUser(customFeature.FeatureId, paidUser.UserId) 1144 | if err != nil { 1145 | t.Fatal(err) 1146 | } 1147 | assert.NotNil(warrantToken) 1148 | 1149 | paidUserHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1150 | RequestOptions: warrant.RequestOptions{ 1151 | WarrantToken: "latest", 1152 | }, 1153 | FeatureId: "custom-feature", 1154 | Subject: warrant.Subject{ 1155 | ObjectType: warrant.ObjectTypeUser, 1156 | ObjectId: paidUser.UserId, 1157 | }, 1158 | }) 1159 | if err != nil { 1160 | t.Fatal(err) 1161 | } 1162 | assert.False(paidUserHasFeature) 1163 | 1164 | paidUserFeaturesList, err = feature.ListFeaturesForUser(paidUser.UserId, &warrant.ListFeatureParams{ 1165 | ListParams: warrant.ListParams{ 1166 | RequestOptions: warrant.RequestOptions{ 1167 | WarrantToken: "latest", 1168 | }, 1169 | Limit: 100, 1170 | }, 1171 | }) 1172 | if err != nil { 1173 | t.Fatal(err) 1174 | } 1175 | assert.Equal(0, len(paidUserFeaturesList.Results)) 1176 | 1177 | // Free user tests 1178 | freeUserHasFeature, err := warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1179 | RequestOptions: warrant.RequestOptions{ 1180 | WarrantToken: "latest", 1181 | }, 1182 | FeatureId: "feature-1", 1183 | Subject: warrant.Subject{ 1184 | ObjectType: warrant.ObjectTypeUser, 1185 | ObjectId: freeUser.UserId, 1186 | }, 1187 | }) 1188 | if err != nil { 1189 | t.Fatal(err) 1190 | } 1191 | assert.False(freeUserHasFeature) 1192 | 1193 | freeTierFeaturesList, err := feature.ListFeaturesForPricingTier("free", &warrant.ListFeatureParams{ 1194 | ListParams: warrant.ListParams{ 1195 | RequestOptions: warrant.RequestOptions{ 1196 | WarrantToken: "latest", 1197 | }, 1198 | Limit: 100, 1199 | }, 1200 | }) 1201 | if err != nil { 1202 | t.Fatal(err) 1203 | } 1204 | assert.Equal(0, len(freeTierFeaturesList.Results)) 1205 | 1206 | freeUserFeaturesList, err := feature.ListFeaturesForUser(freeUser.UserId, &warrant.ListFeatureParams{ 1207 | ListParams: warrant.ListParams{ 1208 | RequestOptions: warrant.RequestOptions{ 1209 | WarrantToken: "latest", 1210 | }, 1211 | Limit: 100, 1212 | }, 1213 | }) 1214 | if err != nil { 1215 | t.Fatal(err) 1216 | } 1217 | assert.Equal(0, len(freeUserFeaturesList.Results)) 1218 | 1219 | // Assign feature-1 -> free tier -> free user 1220 | _, err = feature.AssignFeatureToPricingTier(feature1.FeatureId, freeTier.PricingTierId) 1221 | if err != nil { 1222 | t.Fatal(err) 1223 | } 1224 | 1225 | _, err = pricingtier.AssignPricingTierToUser(freeTier.PricingTierId, freeUser.UserId) 1226 | if err != nil { 1227 | t.Fatal(err) 1228 | } 1229 | 1230 | freeUserHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1231 | RequestOptions: warrant.RequestOptions{ 1232 | WarrantToken: "latest", 1233 | }, 1234 | FeatureId: "feature-1", 1235 | Subject: warrant.Subject{ 1236 | ObjectType: warrant.ObjectTypeUser, 1237 | ObjectId: freeUser.UserId, 1238 | }, 1239 | }) 1240 | if err != nil { 1241 | t.Fatal(err) 1242 | } 1243 | assert.True(freeUserHasFeature) 1244 | 1245 | freeTierFeaturesList, err = feature.ListFeaturesForPricingTier("free", &warrant.ListFeatureParams{ 1246 | ListParams: warrant.ListParams{ 1247 | RequestOptions: warrant.RequestOptions{ 1248 | WarrantToken: "latest", 1249 | }, 1250 | Limit: 100, 1251 | }, 1252 | }) 1253 | if err != nil { 1254 | t.Fatal(err) 1255 | } 1256 | assert.Equal(1, len(freeTierFeaturesList.Results)) 1257 | 1258 | freeUserTiersList, err := pricingtier.ListPricingTiersForUser(freeUser.UserId, &warrant.ListPricingTierParams{ 1259 | ListParams: warrant.ListParams{ 1260 | RequestOptions: warrant.RequestOptions{ 1261 | WarrantToken: "latest", 1262 | }, 1263 | Limit: 100, 1264 | }, 1265 | }) 1266 | if err != nil { 1267 | t.Fatal(err) 1268 | } 1269 | assert.Equal(1, len(freeUserTiersList.Results)) 1270 | assert.Equal("free", freeUserTiersList.Results[0].PricingTierId) 1271 | 1272 | warrantToken, err = feature.RemoveFeatureFromPricingTier(feature1.FeatureId, freeTier.PricingTierId) 1273 | if err != nil { 1274 | t.Fatal(err) 1275 | } 1276 | assert.NotNil(warrantToken) 1277 | 1278 | freeUserHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1279 | RequestOptions: warrant.RequestOptions{ 1280 | WarrantToken: "latest", 1281 | }, 1282 | FeatureId: "feature-1", 1283 | Subject: warrant.Subject{ 1284 | ObjectType: warrant.ObjectTypeUser, 1285 | ObjectId: freeUser.UserId, 1286 | }, 1287 | }) 1288 | if err != nil { 1289 | t.Fatal(err) 1290 | } 1291 | assert.False(freeUserHasFeature) 1292 | 1293 | freeTierFeaturesList, err = feature.ListFeaturesForPricingTier("free", &warrant.ListFeatureParams{ 1294 | ListParams: warrant.ListParams{ 1295 | RequestOptions: warrant.RequestOptions{ 1296 | WarrantToken: "latest", 1297 | }, 1298 | Limit: 100, 1299 | }, 1300 | }) 1301 | if err != nil { 1302 | t.Fatal(err) 1303 | } 1304 | assert.Equal(0, len(freeTierFeaturesList.Results)) 1305 | 1306 | freeUserTiersList, err = pricingtier.ListPricingTiersForUser(freeUser.UserId, &warrant.ListPricingTierParams{ 1307 | ListParams: warrant.ListParams{ 1308 | RequestOptions: warrant.RequestOptions{ 1309 | WarrantToken: "latest", 1310 | }, 1311 | Limit: 100, 1312 | }, 1313 | }) 1314 | if err != nil { 1315 | t.Fatal(err) 1316 | } 1317 | assert.Equal(1, len(freeUserTiersList.Results)) 1318 | 1319 | warrantToken, err = pricingtier.RemovePricingTierFromUser(freeTier.PricingTierId, freeUser.UserId) 1320 | if err != nil { 1321 | t.Fatal(err) 1322 | } 1323 | assert.NotNil(warrantToken) 1324 | 1325 | freeUserTiersList, err = pricingtier.ListPricingTiersForUser(freeUser.UserId, &warrant.ListPricingTierParams{ 1326 | ListParams: warrant.ListParams{ 1327 | RequestOptions: warrant.RequestOptions{ 1328 | WarrantToken: "latest", 1329 | }, 1330 | Limit: 100, 1331 | }, 1332 | }) 1333 | if err != nil { 1334 | t.Fatal(err) 1335 | } 1336 | assert.Equal(0, len(freeUserTiersList.Results)) 1337 | 1338 | // Clean up 1339 | warrantToken, err = user.Delete(freeUser.UserId) 1340 | if err != nil { 1341 | t.Fatal(err) 1342 | } 1343 | assert.NotNil(warrantToken) 1344 | warrantToken, err = user.Delete(paidUser.UserId) 1345 | if err != nil { 1346 | t.Fatal(err) 1347 | } 1348 | assert.NotNil(warrantToken) 1349 | warrantToken, err = pricingtier.Delete(freeTier.PricingTierId) 1350 | if err != nil { 1351 | t.Fatal(err) 1352 | } 1353 | assert.NotNil(warrantToken) 1354 | warrantToken, err = pricingtier.Delete(paidTier.PricingTierId) 1355 | if err != nil { 1356 | t.Fatal(err) 1357 | } 1358 | assert.NotNil(warrantToken) 1359 | warrantToken, err = feature.Delete(customFeature.FeatureId) 1360 | if err != nil { 1361 | t.Fatal(err) 1362 | } 1363 | assert.NotNil(warrantToken) 1364 | warrantToken, err = feature.Delete(feature1.FeatureId) 1365 | if err != nil { 1366 | t.Fatal(err) 1367 | } 1368 | assert.NotNil(warrantToken) 1369 | warrantToken, err = feature.Delete(feature2.FeatureId) 1370 | if err != nil { 1371 | t.Fatal(err) 1372 | } 1373 | assert.NotNil(warrantToken) 1374 | } 1375 | 1376 | func TestPricingTiersAndFeaturesTenants(t *testing.T) { 1377 | setup() 1378 | assert := assert.New(t) 1379 | 1380 | // Create tenants 1381 | freeTenant, err := tenant.Create(&warrant.TenantParams{}) 1382 | if err != nil { 1383 | t.Fatal(err) 1384 | } 1385 | 1386 | paidTenant, err := tenant.Create(&warrant.TenantParams{}) 1387 | if err != nil { 1388 | t.Fatal(err) 1389 | } 1390 | 1391 | // Create pricing tieres 1392 | freeTier, err := pricingtier.Create(&warrant.PricingTierParams{ 1393 | PricingTierId: "free", 1394 | }) 1395 | if err != nil { 1396 | t.Fatal(err) 1397 | } 1398 | 1399 | paidTier, err := pricingtier.Create(&warrant.PricingTierParams{ 1400 | PricingTierId: "paid", 1401 | }) 1402 | if err != nil { 1403 | t.Fatal(err) 1404 | } 1405 | 1406 | // Create features 1407 | customFeature, err := feature.Create(&warrant.FeatureParams{ 1408 | FeatureId: "custom-feature", 1409 | }) 1410 | if err != nil { 1411 | t.Fatal(err) 1412 | } 1413 | 1414 | feature1, err := feature.Create(&warrant.FeatureParams{ 1415 | FeatureId: "feature-1", 1416 | }) 1417 | if err != nil { 1418 | t.Fatal(err) 1419 | } 1420 | 1421 | feature2, err := feature.Create(&warrant.FeatureParams{ 1422 | FeatureId: "feature-2", 1423 | }) 1424 | if err != nil { 1425 | t.Fatal(err) 1426 | } 1427 | 1428 | // Paid tenant tests 1429 | paidTenantHasFeature, err := warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1430 | RequestOptions: warrant.RequestOptions{ 1431 | WarrantToken: "latest", 1432 | }, 1433 | FeatureId: "custom-feature", 1434 | Subject: warrant.Subject{ 1435 | ObjectType: warrant.ObjectTypeTenant, 1436 | ObjectId: paidTenant.TenantId, 1437 | }, 1438 | }) 1439 | if err != nil { 1440 | t.Fatal(err) 1441 | } 1442 | assert.False(paidTenantHasFeature) 1443 | 1444 | paidTenantFeaturesList, err := feature.ListFeaturesForTenant(paidTenant.TenantId, &warrant.ListFeatureParams{ 1445 | ListParams: warrant.ListParams{ 1446 | RequestOptions: warrant.RequestOptions{ 1447 | WarrantToken: "latest", 1448 | }, 1449 | Limit: 100, 1450 | }, 1451 | }) 1452 | if err != nil { 1453 | t.Fatal(err) 1454 | } 1455 | assert.Equal(0, len(paidTenantFeaturesList.Results)) 1456 | 1457 | // Assign custom feature -> paid tenant 1458 | _, err = feature.AssignFeatureToTenant(customFeature.FeatureId, paidTenant.TenantId) 1459 | if err != nil { 1460 | t.Fatal(err) 1461 | } 1462 | 1463 | paidTenantHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1464 | RequestOptions: warrant.RequestOptions{ 1465 | WarrantToken: "latest", 1466 | }, 1467 | FeatureId: "custom-feature", 1468 | Subject: warrant.Subject{ 1469 | ObjectType: warrant.ObjectTypeTenant, 1470 | ObjectId: paidTenant.TenantId, 1471 | }, 1472 | }) 1473 | if err != nil { 1474 | t.Fatal(err) 1475 | } 1476 | assert.True(paidTenantHasFeature) 1477 | 1478 | paidTenantFeaturesList, err = feature.ListFeaturesForTenant(paidTenant.TenantId, &warrant.ListFeatureParams{ 1479 | ListParams: warrant.ListParams{ 1480 | RequestOptions: warrant.RequestOptions{ 1481 | WarrantToken: "latest", 1482 | }, 1483 | Limit: 100, 1484 | }, 1485 | }) 1486 | if err != nil { 1487 | t.Fatal(err) 1488 | } 1489 | assert.Equal(1, len(paidTenantFeaturesList.Results)) 1490 | assert.Equal("custom-feature", paidTenantFeaturesList.Results[0].FeatureId) 1491 | 1492 | warrantToken, err := feature.RemoveFeatureFromTenant(customFeature.FeatureId, paidTenant.TenantId) 1493 | if err != nil { 1494 | t.Fatal(err) 1495 | } 1496 | assert.NotNil(warrantToken) 1497 | 1498 | paidTenantHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1499 | RequestOptions: warrant.RequestOptions{ 1500 | WarrantToken: "latest", 1501 | }, 1502 | FeatureId: "custom-feature", 1503 | Subject: warrant.Subject{ 1504 | ObjectType: warrant.ObjectTypeTenant, 1505 | ObjectId: paidTenant.TenantId, 1506 | }, 1507 | }) 1508 | if err != nil { 1509 | t.Fatal(err) 1510 | } 1511 | assert.False(paidTenantHasFeature) 1512 | 1513 | paidTenantFeaturesList, err = feature.ListFeaturesForTenant(paidTenant.TenantId, &warrant.ListFeatureParams{ 1514 | ListParams: warrant.ListParams{ 1515 | RequestOptions: warrant.RequestOptions{ 1516 | WarrantToken: "latest", 1517 | }, 1518 | Limit: 100, 1519 | }, 1520 | }) 1521 | if err != nil { 1522 | t.Fatal(err) 1523 | } 1524 | assert.Equal(0, len(paidTenantFeaturesList.Results)) 1525 | 1526 | // Free tenant tests 1527 | freeTenantHasFeature, err := warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1528 | RequestOptions: warrant.RequestOptions{ 1529 | WarrantToken: "latest", 1530 | }, 1531 | FeatureId: "feature-1", 1532 | Subject: warrant.Subject{ 1533 | ObjectType: warrant.ObjectTypeTenant, 1534 | ObjectId: freeTenant.TenantId, 1535 | }, 1536 | }) 1537 | if err != nil { 1538 | t.Fatal(err) 1539 | } 1540 | assert.False(freeTenantHasFeature) 1541 | 1542 | freeTierFeaturesList, err := feature.ListFeaturesForPricingTier("free", &warrant.ListFeatureParams{ 1543 | ListParams: warrant.ListParams{ 1544 | RequestOptions: warrant.RequestOptions{ 1545 | WarrantToken: "latest", 1546 | }, 1547 | Limit: 100, 1548 | }, 1549 | }) 1550 | if err != nil { 1551 | t.Fatal(err) 1552 | } 1553 | assert.Equal(0, len(freeTierFeaturesList.Results)) 1554 | 1555 | freeTenantFeaturesList, err := feature.ListFeaturesForTenant(freeTenant.TenantId, &warrant.ListFeatureParams{ 1556 | ListParams: warrant.ListParams{ 1557 | RequestOptions: warrant.RequestOptions{ 1558 | WarrantToken: "latest", 1559 | }, 1560 | Limit: 100, 1561 | }, 1562 | }) 1563 | if err != nil { 1564 | t.Fatal(err) 1565 | } 1566 | assert.Equal(0, len(freeTenantFeaturesList.Results)) 1567 | 1568 | // Assign feature-1 -> free tier -> free tenant 1569 | _, err = feature.AssignFeatureToPricingTier(feature1.FeatureId, freeTier.PricingTierId) 1570 | if err != nil { 1571 | t.Fatal(err) 1572 | } 1573 | 1574 | _, err = pricingtier.AssignPricingTierToTenant(freeTier.PricingTierId, freeTenant.TenantId) 1575 | if err != nil { 1576 | t.Fatal(err) 1577 | } 1578 | 1579 | freeTenantHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1580 | RequestOptions: warrant.RequestOptions{ 1581 | WarrantToken: "latest", 1582 | }, 1583 | FeatureId: "feature-1", 1584 | Subject: warrant.Subject{ 1585 | ObjectType: warrant.ObjectTypeTenant, 1586 | ObjectId: freeTenant.TenantId, 1587 | }, 1588 | }) 1589 | if err != nil { 1590 | t.Fatal(err) 1591 | } 1592 | assert.True(freeTenantHasFeature) 1593 | 1594 | freeTierFeaturesList, err = feature.ListFeaturesForPricingTier("free", &warrant.ListFeatureParams{ 1595 | ListParams: warrant.ListParams{ 1596 | RequestOptions: warrant.RequestOptions{ 1597 | WarrantToken: "latest", 1598 | }, 1599 | Limit: 100, 1600 | }, 1601 | }) 1602 | if err != nil { 1603 | t.Fatal(err) 1604 | } 1605 | assert.Equal(1, len(freeTierFeaturesList.Results)) 1606 | 1607 | freeTenantTiersList, err := pricingtier.ListPricingTiersForTenant(freeTenant.TenantId, &warrant.ListPricingTierParams{ 1608 | ListParams: warrant.ListParams{ 1609 | RequestOptions: warrant.RequestOptions{ 1610 | WarrantToken: "latest", 1611 | }, 1612 | Limit: 100, 1613 | }, 1614 | }) 1615 | if err != nil { 1616 | t.Fatal(err) 1617 | } 1618 | assert.Equal(1, len(freeTenantTiersList.Results)) 1619 | assert.Equal("free", freeTenantTiersList.Results[0].PricingTierId) 1620 | 1621 | warrantToken, err = feature.RemoveFeatureFromPricingTier(feature1.FeatureId, freeTier.PricingTierId) 1622 | if err != nil { 1623 | t.Fatal(err) 1624 | } 1625 | assert.NotNil(warrantToken) 1626 | 1627 | freeTenantHasFeature, err = warrant.CheckHasFeature(&warrant.FeatureCheckParams{ 1628 | RequestOptions: warrant.RequestOptions{ 1629 | WarrantToken: "latest", 1630 | }, 1631 | FeatureId: "feature-1", 1632 | Subject: warrant.Subject{ 1633 | ObjectType: warrant.ObjectTypeTenant, 1634 | ObjectId: freeTenant.TenantId, 1635 | }, 1636 | }) 1637 | if err != nil { 1638 | t.Fatal(err) 1639 | } 1640 | assert.False(freeTenantHasFeature) 1641 | 1642 | freeTierFeaturesList, err = feature.ListFeaturesForPricingTier("free", &warrant.ListFeatureParams{ 1643 | ListParams: warrant.ListParams{ 1644 | RequestOptions: warrant.RequestOptions{ 1645 | WarrantToken: "latest", 1646 | }, 1647 | Limit: 100, 1648 | }, 1649 | }) 1650 | if err != nil { 1651 | t.Fatal(err) 1652 | } 1653 | assert.Equal(0, len(freeTierFeaturesList.Results)) 1654 | 1655 | freeTenantTiersList, err = pricingtier.ListPricingTiersForTenant(freeTenant.TenantId, &warrant.ListPricingTierParams{ 1656 | ListParams: warrant.ListParams{ 1657 | RequestOptions: warrant.RequestOptions{ 1658 | WarrantToken: "latest", 1659 | }, 1660 | Limit: 100, 1661 | }, 1662 | }) 1663 | if err != nil { 1664 | t.Fatal(err) 1665 | } 1666 | assert.Equal(1, len(freeTenantTiersList.Results)) 1667 | 1668 | warrantToken, err = pricingtier.RemovePricingTierFromTenant(freeTier.PricingTierId, freeTenant.TenantId) 1669 | if err != nil { 1670 | t.Fatal(err) 1671 | } 1672 | assert.NotNil(warrantToken) 1673 | 1674 | freeTenantTiersList, err = pricingtier.ListPricingTiersForTenant(freeTenant.TenantId, &warrant.ListPricingTierParams{ 1675 | ListParams: warrant.ListParams{ 1676 | RequestOptions: warrant.RequestOptions{ 1677 | WarrantToken: "latest", 1678 | }, 1679 | Limit: 100, 1680 | }, 1681 | }) 1682 | if err != nil { 1683 | t.Fatal(err) 1684 | } 1685 | assert.Equal(0, len(freeTenantTiersList.Results)) 1686 | 1687 | // Clean up 1688 | warrantToken, err = tenant.Delete(freeTenant.TenantId) 1689 | if err != nil { 1690 | t.Fatal(err) 1691 | } 1692 | assert.NotNil(warrantToken) 1693 | warrantToken, err = tenant.Delete(paidTenant.TenantId) 1694 | if err != nil { 1695 | t.Fatal(err) 1696 | } 1697 | assert.NotNil(warrantToken) 1698 | warrantToken, err = pricingtier.Delete(freeTier.PricingTierId) 1699 | if err != nil { 1700 | t.Fatal(err) 1701 | } 1702 | assert.NotNil(warrantToken) 1703 | warrantToken, err = pricingtier.Delete(paidTier.PricingTierId) 1704 | if err != nil { 1705 | t.Fatal(err) 1706 | } 1707 | assert.NotNil(warrantToken) 1708 | warrantToken, err = feature.Delete(customFeature.FeatureId) 1709 | if err != nil { 1710 | t.Fatal(err) 1711 | } 1712 | assert.NotNil(warrantToken) 1713 | warrantToken, err = feature.Delete(feature1.FeatureId) 1714 | if err != nil { 1715 | t.Fatal(err) 1716 | } 1717 | assert.NotNil(warrantToken) 1718 | warrantToken, err = feature.Delete(feature2.FeatureId) 1719 | if err != nil { 1720 | t.Fatal(err) 1721 | } 1722 | assert.NotNil(warrantToken) 1723 | } 1724 | 1725 | func TestSessions(t *testing.T) { 1726 | setup() 1727 | assert := assert.New(t) 1728 | 1729 | user1, err := user.Create(&warrant.UserParams{}) 1730 | if err != nil { 1731 | t.Fatal(err) 1732 | } 1733 | 1734 | tenant1, err := tenant.Create(&warrant.TenantParams{}) 1735 | if err != nil { 1736 | t.Fatal(err) 1737 | } 1738 | 1739 | _, err = user.AssignUserToTenant(user1.UserId, tenant1.TenantId, "admin") 1740 | if err != nil { 1741 | t.Fatal(err) 1742 | } 1743 | 1744 | authzSessionToken, err := session.CreateAuthorizationSession(&warrant.AuthorizationSessionParams{ 1745 | UserId: user1.UserId, 1746 | }) 1747 | if err != nil { 1748 | t.Fatal(err) 1749 | } 1750 | assert.NotEmpty(authzSessionToken) 1751 | 1752 | authzSessionTokenWithTenant, err := session.CreateAuthorizationSession(&warrant.AuthorizationSessionParams{ 1753 | UserId: user1.UserId, 1754 | TenantId: tenant1.TenantId, 1755 | }) 1756 | if err != nil { 1757 | t.Fatal(err) 1758 | } 1759 | assert.NotEmpty(authzSessionTokenWithTenant) 1760 | 1761 | ssDashUrl, err := session.CreateSelfServiceSession(&warrant.SelfServiceSessionParams{ 1762 | UserId: user1.UserId, 1763 | TenantId: tenant1.TenantId, 1764 | RedirectUrl: "http://localhost:8080", 1765 | SelfServiceStrategy: warrant.SelfServiceStrategyFGAC, 1766 | }) 1767 | if err != nil { 1768 | t.Fatal(err) 1769 | } 1770 | assert.NotEmpty(ssDashUrl) 1771 | 1772 | // Clean up 1773 | warrantToken, err := user.Delete(user1.UserId) 1774 | if err != nil { 1775 | t.Fatal(err) 1776 | } 1777 | assert.NotNil(warrantToken) 1778 | 1779 | warrantToken, err = tenant.Delete(tenant1.TenantId) 1780 | if err != nil { 1781 | t.Fatal(err) 1782 | } 1783 | assert.NotNil(warrantToken) 1784 | } 1785 | 1786 | func TestWarrants(t *testing.T) { 1787 | setup() 1788 | assert := assert.New(t) 1789 | 1790 | newUser, err := user.Create(&warrant.UserParams{}) 1791 | if err != nil { 1792 | t.Fatal(err) 1793 | } 1794 | 1795 | permission1, err := permission.Create(&warrant.PermissionParams{ 1796 | PermissionId: "perm1", 1797 | Meta: map[string]interface{}{ 1798 | "name": "Permission 1", 1799 | "description": "Permission with id 1", 1800 | }, 1801 | }) 1802 | if err != nil { 1803 | t.Fatal(err) 1804 | } 1805 | 1806 | permission2, err := permission.Create(&warrant.PermissionParams{ 1807 | PermissionId: "perm2", 1808 | Meta: map[string]interface{}{ 1809 | "name": "Permission 2", 1810 | "description": "Permission with id 2", 1811 | }, 1812 | }) 1813 | if err != nil { 1814 | t.Fatal(err) 1815 | } 1816 | 1817 | checkResult, err := warrant.Check(&warrant.WarrantCheckParams{ 1818 | RequestOptions: warrant.RequestOptions{ 1819 | WarrantToken: "latest", 1820 | }, 1821 | WarrantCheck: warrant.WarrantCheck{ 1822 | Object: warrant.Object{ 1823 | ObjectType: warrant.ObjectTypePermission, 1824 | ObjectId: permission1.PermissionId, 1825 | }, 1826 | Relation: "member", 1827 | Subject: warrant.Subject{ 1828 | ObjectType: warrant.ObjectTypeUser, 1829 | ObjectId: newUser.UserId, 1830 | }, 1831 | }, 1832 | }) 1833 | if err != nil { 1834 | t.Fatal(err) 1835 | } 1836 | assert.False(checkResult) 1837 | 1838 | permission1Warrant, err := warrant.Create(&warrant.WarrantParams{ 1839 | ObjectType: warrant.ObjectTypePermission, 1840 | ObjectId: permission1.PermissionId, 1841 | Relation: "member", 1842 | Subject: warrant.Subject{ 1843 | ObjectType: warrant.ObjectTypeUser, 1844 | ObjectId: newUser.UserId, 1845 | }, 1846 | }) 1847 | if err != nil { 1848 | t.Fatal(err) 1849 | } 1850 | assert.NotNil(permission1Warrant.WarrantToken) 1851 | 1852 | checkResult, err = warrant.Check(&warrant.WarrantCheckParams{ 1853 | RequestOptions: warrant.RequestOptions{ 1854 | WarrantToken: "latest", 1855 | }, 1856 | WarrantCheck: warrant.WarrantCheck{ 1857 | Object: warrant.Object{ 1858 | ObjectType: warrant.ObjectTypePermission, 1859 | ObjectId: permission1.PermissionId, 1860 | }, 1861 | Relation: "member", 1862 | Subject: warrant.Subject{ 1863 | ObjectType: warrant.ObjectTypeUser, 1864 | ObjectId: newUser.UserId, 1865 | }, 1866 | }, 1867 | }) 1868 | if err != nil { 1869 | t.Fatal(err) 1870 | } 1871 | assert.True(checkResult) 1872 | 1873 | permission2Warrant, err := warrant.Create(&warrant.WarrantParams{ 1874 | ObjectType: warrant.ObjectTypePermission, 1875 | ObjectId: permission2.PermissionId, 1876 | Relation: "member", 1877 | Subject: warrant.Subject{ 1878 | ObjectType: warrant.ObjectTypeUser, 1879 | ObjectId: newUser.UserId, 1880 | }, 1881 | }) 1882 | if err != nil { 1883 | t.Fatal(err) 1884 | } 1885 | assert.NotNil(permission2Warrant.WarrantToken) 1886 | 1887 | warrantsList, err := warrant.ListWarrants(&warrant.ListWarrantParams{ 1888 | ObjectType: warrant.ObjectTypePermission, 1889 | ObjectId: permission1.PermissionId, 1890 | }) 1891 | if err != nil { 1892 | t.Fatal(err) 1893 | } 1894 | 1895 | assert.Equal(1, len(warrantsList.Results)) 1896 | assert.Equal("permission", warrantsList.Results[0].ObjectType) 1897 | assert.Equal("perm1", warrantsList.Results[0].ObjectId) 1898 | assert.Equal("member", warrantsList.Results[0].Relation) 1899 | assert.Equal("user", warrantsList.Results[0].Subject.ObjectType) 1900 | assert.Equal(newUser.UserId, warrantsList.Results[0].Subject.ObjectId) 1901 | 1902 | warrantsList, err = warrant.ListWarrants(&warrant.ListWarrantParams{ 1903 | SubjectType: warrant.ObjectTypeUser, 1904 | SubjectId: newUser.UserId, 1905 | }) 1906 | if err != nil { 1907 | t.Fatal(err) 1908 | } 1909 | 1910 | assert.Equal(2, len(warrantsList.Results)) 1911 | assert.Equal("permission", warrantsList.Results[0].ObjectType) 1912 | assert.Equal("perm1", warrantsList.Results[0].ObjectId) 1913 | assert.Equal("member", warrantsList.Results[0].Relation) 1914 | assert.Equal("user", warrantsList.Results[0].Subject.ObjectType) 1915 | assert.Equal(newUser.UserId, warrantsList.Results[0].Subject.ObjectId) 1916 | assert.Equal("permission", warrantsList.Results[1].ObjectType) 1917 | assert.Equal("perm2", warrantsList.Results[1].ObjectId) 1918 | assert.Equal("member", warrantsList.Results[1].Relation) 1919 | assert.Equal("user", warrantsList.Results[1].Subject.ObjectType) 1920 | assert.Equal(newUser.UserId, warrantsList.Results[1].Subject.ObjectId) 1921 | 1922 | queryResult, err := warrant.Query(fmt.Sprintf("select * where %s:%s is *", "user", newUser.UserId), &warrant.QueryParams{}) 1923 | if err != nil { 1924 | fmt.Println(err) 1925 | return 1926 | } 1927 | 1928 | assert.Equal(2, len(queryResult.Results)) 1929 | assert.Equal("permission", queryResult.Results[0].ObjectType) 1930 | assert.Equal("perm1", queryResult.Results[0].ObjectId) 1931 | assert.Equal("member", queryResult.Results[0].Relation) 1932 | assert.NotNil(queryResult.Results[0].Meta) 1933 | assert.Equal("Permission 1", queryResult.Results[0].Meta["name"]) 1934 | assert.Equal("Permission with id 1", queryResult.Results[0].Meta["description"]) 1935 | assert.Equal("permission", queryResult.Results[1].ObjectType) 1936 | assert.Equal("perm2", queryResult.Results[1].ObjectId) 1937 | assert.Equal("member", queryResult.Results[1].Relation) 1938 | assert.NotNil(queryResult.Results[1].Meta) 1939 | assert.Equal("Permission 2", queryResult.Results[1].Meta["name"]) 1940 | assert.Equal("Permission with id 2", queryResult.Results[1].Meta["description"]) 1941 | 1942 | warrantToken, err := warrant.Delete(&warrant.WarrantParams{ 1943 | ObjectType: warrant.ObjectTypePermission, 1944 | ObjectId: permission1.PermissionId, 1945 | Relation: "member", 1946 | Subject: warrant.Subject{ 1947 | ObjectType: warrant.ObjectTypeUser, 1948 | ObjectId: newUser.UserId, 1949 | }, 1950 | }) 1951 | if err != nil { 1952 | t.Fatal(err) 1953 | } 1954 | assert.NotNil(warrantToken) 1955 | 1956 | checkResult, err = warrant.Check(&warrant.WarrantCheckParams{ 1957 | RequestOptions: warrant.RequestOptions{ 1958 | WarrantToken: "latest", 1959 | }, 1960 | WarrantCheck: warrant.WarrantCheck{ 1961 | Object: warrant.Object{ 1962 | ObjectType: warrant.ObjectTypePermission, 1963 | ObjectId: permission1.PermissionId, 1964 | }, 1965 | Relation: "member", 1966 | Subject: warrant.Subject{ 1967 | ObjectType: warrant.ObjectTypeUser, 1968 | ObjectId: newUser.UserId, 1969 | }, 1970 | }, 1971 | }) 1972 | if err != nil { 1973 | t.Fatal(err) 1974 | } 1975 | assert.False(checkResult) 1976 | 1977 | // Clean up 1978 | warrantToken, err = user.Delete(newUser.UserId) 1979 | if err != nil { 1980 | t.Fatal(err) 1981 | } 1982 | assert.NotNil(warrantToken) 1983 | 1984 | warrantToken, err = permission.Delete(permission1.PermissionId) 1985 | if err != nil { 1986 | t.Fatal(err) 1987 | } 1988 | assert.NotNil(warrantToken) 1989 | 1990 | warrantToken, err = permission.Delete(permission2.PermissionId) 1991 | if err != nil { 1992 | t.Fatal(err) 1993 | } 1994 | assert.NotNil(warrantToken) 1995 | } 1996 | 1997 | func TestBatchWarrants(t *testing.T) { 1998 | setup() 1999 | assert := assert.New(t) 2000 | 2001 | newUser, err := user.Create(&warrant.UserParams{}) 2002 | if err != nil { 2003 | t.Fatal(err) 2004 | } 2005 | 2006 | permission1, err := permission.Create(&warrant.PermissionParams{ 2007 | PermissionId: "perm1", 2008 | Meta: map[string]interface{}{ 2009 | "name": "Permission 1", 2010 | "description": "Permission 1", 2011 | }, 2012 | }) 2013 | if err != nil { 2014 | t.Fatal(err) 2015 | } 2016 | 2017 | permission2, err := permission.Create(&warrant.PermissionParams{ 2018 | PermissionId: "perm2", 2019 | Meta: map[string]interface{}{ 2020 | "name": "Permission 2", 2021 | "description": "Permission 2", 2022 | }, 2023 | }) 2024 | if err != nil { 2025 | t.Fatal(err) 2026 | } 2027 | 2028 | userHasPermission1, err := warrant.Check(&warrant.WarrantCheckParams{ 2029 | RequestOptions: warrant.RequestOptions{ 2030 | WarrantToken: "latest", 2031 | }, 2032 | WarrantCheck: warrant.WarrantCheck{ 2033 | Object: permission1, 2034 | Relation: "member", 2035 | Subject: newUser, 2036 | }, 2037 | }) 2038 | if err != nil { 2039 | t.Fatal(err) 2040 | } 2041 | assert.False(userHasPermission1) 2042 | 2043 | userHasPermission2, err := warrant.Check(&warrant.WarrantCheckParams{ 2044 | RequestOptions: warrant.RequestOptions{ 2045 | WarrantToken: "latest", 2046 | }, 2047 | WarrantCheck: warrant.WarrantCheck{ 2048 | Object: permission2, 2049 | Relation: "member", 2050 | Subject: newUser, 2051 | }, 2052 | }) 2053 | if err != nil { 2054 | t.Fatal(err) 2055 | } 2056 | assert.False(userHasPermission2) 2057 | 2058 | warrants, err := warrant.BatchCreate([]warrant.WarrantParams{ 2059 | { 2060 | ObjectType: warrant.ObjectTypePermission, 2061 | ObjectId: permission1.PermissionId, 2062 | Relation: "member", 2063 | Subject: warrant.Subject{ 2064 | ObjectType: warrant.ObjectTypeUser, 2065 | ObjectId: newUser.UserId, 2066 | }, 2067 | }, 2068 | { 2069 | ObjectType: warrant.ObjectTypePermission, 2070 | ObjectId: permission2.PermissionId, 2071 | Relation: "member", 2072 | Subject: warrant.Subject{ 2073 | ObjectType: warrant.ObjectTypeUser, 2074 | ObjectId: newUser.UserId, 2075 | }, 2076 | }, 2077 | }) 2078 | if err != nil { 2079 | t.Fatal(err) 2080 | } 2081 | assert.Len(warrants, 2) 2082 | assert.NotNil(warrants[0].WarrantToken) 2083 | assert.NotNil(warrants[1].WarrantToken) 2084 | 2085 | userHasPermission1, err = warrant.Check(&warrant.WarrantCheckParams{ 2086 | RequestOptions: warrant.RequestOptions{ 2087 | WarrantToken: "latest", 2088 | }, 2089 | WarrantCheck: warrant.WarrantCheck{ 2090 | Object: permission1, 2091 | Relation: "member", 2092 | Subject: newUser, 2093 | }, 2094 | }) 2095 | if err != nil { 2096 | t.Fatal(err) 2097 | } 2098 | assert.True(userHasPermission1) 2099 | 2100 | userHasPermission2, err = warrant.Check(&warrant.WarrantCheckParams{ 2101 | RequestOptions: warrant.RequestOptions{ 2102 | WarrantToken: "latest", 2103 | }, 2104 | WarrantCheck: warrant.WarrantCheck{ 2105 | Object: permission2, 2106 | Relation: "member", 2107 | Subject: newUser, 2108 | }, 2109 | }) 2110 | if err != nil { 2111 | t.Fatal(err) 2112 | } 2113 | assert.True(userHasPermission2) 2114 | 2115 | warrantToken, err := warrant.BatchDelete([]warrant.WarrantParams{ 2116 | { 2117 | ObjectType: warrant.ObjectTypePermission, 2118 | ObjectId: permission1.PermissionId, 2119 | Relation: "member", 2120 | Subject: warrant.Subject{ 2121 | ObjectType: warrant.ObjectTypeUser, 2122 | ObjectId: newUser.UserId, 2123 | }, 2124 | }, 2125 | { 2126 | ObjectType: warrant.ObjectTypePermission, 2127 | ObjectId: permission2.PermissionId, 2128 | Relation: "member", 2129 | Subject: warrant.Subject{ 2130 | ObjectType: warrant.ObjectTypeUser, 2131 | ObjectId: newUser.UserId, 2132 | }, 2133 | }, 2134 | }) 2135 | if err != nil { 2136 | t.Fatal(err) 2137 | } 2138 | assert.NotNil(warrantToken) 2139 | 2140 | warrantToken, err = object.BatchDelete([]warrant.ObjectParams{ 2141 | {ObjectType: warrant.ObjectTypePermission, ObjectId: permission1.PermissionId}, 2142 | {ObjectType: warrant.ObjectTypePermission, ObjectId: permission2.PermissionId}, 2143 | {ObjectType: warrant.ObjectTypeUser, ObjectId: newUser.UserId}, 2144 | }) 2145 | assert.NotNil(warrantToken) 2146 | if err != nil { 2147 | t.Fatal(err) 2148 | } 2149 | } 2150 | 2151 | func TestWarrantPolicies(t *testing.T) { 2152 | setup() 2153 | assert := assert.New(t) 2154 | 2155 | newUser, err := user.Create(&warrant.UserParams{ 2156 | UserId: "user-1", 2157 | }) 2158 | if err != nil { 2159 | t.Fatal(err) 2160 | } 2161 | 2162 | newPermission, err := permission.Create(&warrant.PermissionParams{ 2163 | PermissionId: "test-permission", 2164 | }) 2165 | if err != nil { 2166 | t.Fatal(err) 2167 | } 2168 | 2169 | _, err = warrant.Create(&warrant.WarrantParams{ 2170 | ObjectType: warrant.ObjectTypePermission, 2171 | ObjectId: newPermission.PermissionId, 2172 | Relation: "member", 2173 | Subject: warrant.Subject{ 2174 | ObjectType: warrant.ObjectTypeUser, 2175 | ObjectId: newUser.UserId, 2176 | }, 2177 | Policy: `geo == "us"`, 2178 | }) 2179 | if err != nil { 2180 | t.Fatal(err) 2181 | } 2182 | 2183 | checkResult, err := warrant.Check(&warrant.WarrantCheckParams{ 2184 | RequestOptions: warrant.RequestOptions{ 2185 | WarrantToken: "latest", 2186 | }, 2187 | WarrantCheck: warrant.WarrantCheck{ 2188 | Object: warrant.Object{ 2189 | ObjectType: warrant.ObjectTypePermission, 2190 | ObjectId: newPermission.PermissionId, 2191 | }, 2192 | Relation: "member", 2193 | Subject: warrant.Subject{ 2194 | ObjectType: warrant.ObjectTypeUser, 2195 | ObjectId: "user-1", 2196 | }, 2197 | Context: warrant.PolicyContext{ 2198 | "geo": "us", 2199 | }, 2200 | }, 2201 | }) 2202 | if err != nil { 2203 | t.Fatal(err) 2204 | } 2205 | assert.True(checkResult) 2206 | 2207 | checkResult, err = warrant.Check(&warrant.WarrantCheckParams{ 2208 | RequestOptions: warrant.RequestOptions{ 2209 | WarrantToken: "latest", 2210 | }, 2211 | WarrantCheck: warrant.WarrantCheck{ 2212 | Object: warrant.Object{ 2213 | ObjectType: warrant.ObjectTypePermission, 2214 | ObjectId: newPermission.PermissionId, 2215 | }, 2216 | Relation: "member", 2217 | Subject: warrant.Subject{ 2218 | ObjectType: warrant.ObjectTypeUser, 2219 | ObjectId: "user-1", 2220 | }, 2221 | Context: warrant.PolicyContext{ 2222 | "geo": "gb", 2223 | }, 2224 | }, 2225 | }) 2226 | if err != nil { 2227 | t.Fatal(err) 2228 | } 2229 | assert.False(checkResult) 2230 | 2231 | // Clean up 2232 | warrantToken, err := warrant.Delete(&warrant.WarrantParams{ 2233 | ObjectType: warrant.ObjectTypePermission, 2234 | ObjectId: newPermission.PermissionId, 2235 | Relation: "member", 2236 | Subject: warrant.Subject{ 2237 | ObjectType: warrant.ObjectTypeUser, 2238 | ObjectId: "user-1", 2239 | }, 2240 | Policy: `geo == "us"`, 2241 | }) 2242 | if err != nil { 2243 | t.Fatal(err) 2244 | } 2245 | assert.NotNil(warrantToken) 2246 | 2247 | warrantToken, err = user.Delete(newUser.UserId) 2248 | if err != nil { 2249 | t.Fatal(err) 2250 | } 2251 | assert.NotNil(warrantToken) 2252 | 2253 | warrantToken, err = permission.Delete(newPermission.PermissionId) 2254 | if err != nil { 2255 | t.Fatal(err) 2256 | } 2257 | assert.NotNil(warrantToken) 2258 | } 2259 | 2260 | func TestObjectTypes(t *testing.T) { 2261 | setup() 2262 | assert := assert.New(t) 2263 | 2264 | relations := make(map[string]interface{}) 2265 | relations["relation-1"] = struct{}{} 2266 | 2267 | newType, err := objecttype.Create(&warrant.ObjectTypeParams{ 2268 | Type: "new-type", 2269 | Relations: relations, 2270 | }) 2271 | if err != nil { 2272 | t.Fatal(err) 2273 | } 2274 | assert.Equal("new-type", newType.Type) 2275 | assert.NotNil(newType.Relations["relation-1"]) 2276 | assert.Nil(newType.Relations["relation-2"]) 2277 | assert.NotNil(newType.WarrantToken) 2278 | 2279 | objType, err := objecttype.Get("new-type", &warrant.ObjectTypeParams{}) 2280 | if err != nil { 2281 | t.Fatal(err) 2282 | } 2283 | assert.Equal("new-type", objType.Type) 2284 | assert.Len(objType.Relations, 1) 2285 | assert.NotNil(objType.Relations["relation-1"]) 2286 | 2287 | typesList, err := objecttype.ListObjectTypes(&warrant.ListObjectTypeParams{}) 2288 | if err != nil { 2289 | t.Fatal(err) 2290 | } 2291 | assert.Len(typesList.Results, 7) 2292 | 2293 | newRelations := make(map[string]interface{}) 2294 | newRelations["relation-1"] = struct{}{} 2295 | newRelations["relation-2"] = struct{}{} 2296 | objType, err = objecttype.Update("new-type", &warrant.ObjectTypeParams{ 2297 | Type: "new-type", 2298 | Relations: newRelations, 2299 | }) 2300 | if err != nil { 2301 | t.Fatal(err) 2302 | } 2303 | assert.Equal("new-type", objType.Type) 2304 | assert.Len(objType.Relations, 2) 2305 | assert.NotNil(objType.Relations["relation-1"]) 2306 | assert.NotNil(objType.Relations["relation-2"]) 2307 | assert.NotNil(objType.WarrantToken) 2308 | 2309 | warrantToken, err := objecttype.Delete("new-type") 2310 | if err != nil { 2311 | t.Fatal(err) 2312 | } 2313 | assert.NotNil(warrantToken) 2314 | 2315 | typesList, err = objecttype.ListObjectTypes(&warrant.ListObjectTypeParams{}) 2316 | if err != nil { 2317 | t.Fatal(err) 2318 | } 2319 | assert.Len(typesList.Results, 6) 2320 | } 2321 | 2322 | func TestObjects(t *testing.T) { 2323 | setup() 2324 | assert := assert.New(t) 2325 | 2326 | newObj, err := object.Create(&warrant.ObjectParams{ 2327 | ObjectType: "role", 2328 | ObjectId: "admin2", 2329 | }) 2330 | if err != nil { 2331 | t.Fatal(err) 2332 | } 2333 | assert.Equal("role", newObj.ObjectType) 2334 | assert.Equal("admin2", newObj.ObjectId) 2335 | assert.Len(newObj.Meta, 0) 2336 | 2337 | obj, err := object.Get("role", "admin2", &warrant.ObjectParams{}) 2338 | if err != nil { 2339 | t.Fatal(err) 2340 | } 2341 | assert.Equal("role", obj.ObjectType) 2342 | assert.Equal("admin2", obj.ObjectId) 2343 | assert.Len(obj.Meta, 0) 2344 | 2345 | objectsList, err := object.ListObjects(&warrant.ListObjectParams{}) 2346 | if err != nil { 2347 | t.Fatal(err) 2348 | } 2349 | assert.Len(objectsList.Results, 1) 2350 | assert.Equal("role", objectsList.Results[0].ObjectType) 2351 | assert.Equal("admin2", objectsList.Results[0].ObjectId) 2352 | 2353 | meta := make(map[string]interface{}) 2354 | meta["name"] = "new name" 2355 | obj, err = object.Update("role", "admin2", &warrant.ObjectParams{ 2356 | ObjectType: "role", 2357 | ObjectId: "admin2", 2358 | Meta: meta, 2359 | }) 2360 | if err != nil { 2361 | t.Fatal(err) 2362 | } 2363 | assert.Equal("role", obj.ObjectType) 2364 | assert.Equal("admin2", obj.ObjectId) 2365 | assert.Len(obj.Meta, 1) 2366 | assert.Equal("new name", obj.Meta["name"]) 2367 | 2368 | warrantToken, err := object.Delete("role", "admin2") 2369 | if err != nil { 2370 | t.Fatal(err) 2371 | } 2372 | assert.NotNil(warrantToken) 2373 | 2374 | objectsList, err = object.ListObjects(&warrant.ListObjectParams{}) 2375 | if err != nil { 2376 | t.Fatal(err) 2377 | } 2378 | assert.Len(objectsList.Results, 0) 2379 | } 2380 | 2381 | func TestBatchObjects(t *testing.T) { 2382 | setup() 2383 | assert := assert.New(t) 2384 | 2385 | createdObjects, err := object.BatchCreate([]warrant.ObjectParams{ 2386 | {ObjectType: "document", ObjectId: "document-a"}, 2387 | {ObjectType: "document", ObjectId: "document-b"}, 2388 | {ObjectType: "folder", ObjectId: "resources", Meta: map[string]interface{}{"description": "Helpful documents"}}, 2389 | }) 2390 | if err != nil { 2391 | t.Fatal(err) 2392 | } 2393 | assert.Len(createdObjects, 3) 2394 | 2395 | fetchedObjects, err := object.ListObjects(&warrant.ListObjectParams{ 2396 | ListParams: warrant.ListParams{ 2397 | RequestOptions: warrant.RequestOptions{ 2398 | WarrantToken: "latest", 2399 | }, 2400 | Limit: 10, 2401 | }, 2402 | }) 2403 | if err != nil { 2404 | t.Fatal(err) 2405 | } 2406 | assert.Len(fetchedObjects.Results, 3) 2407 | assert.Equal("document", fetchedObjects.Results[0].ObjectType) 2408 | assert.Equal("document-a", fetchedObjects.Results[0].ObjectId) 2409 | assert.Equal("document", fetchedObjects.Results[1].ObjectType) 2410 | assert.Equal("document-b", fetchedObjects.Results[1].ObjectId) 2411 | assert.Equal("folder", fetchedObjects.Results[2].ObjectType) 2412 | assert.Equal("resources", fetchedObjects.Results[2].ObjectId) 2413 | assert.Equal(map[string]interface{}{"description": "Helpful documents"}, fetchedObjects.Results[2].Meta) 2414 | 2415 | fetchedObjects, err = object.ListObjects(&warrant.ListObjectParams{ 2416 | ListParams: warrant.ListParams{ 2417 | RequestOptions: warrant.RequestOptions{ 2418 | WarrantToken: "latest", 2419 | }, 2420 | Limit: 10, 2421 | }, 2422 | Query: "resource", 2423 | }) 2424 | if err != nil { 2425 | t.Fatal(err) 2426 | } 2427 | assert.Len(fetchedObjects.Results, 1) 2428 | assert.Equal("folder", fetchedObjects.Results[0].ObjectType) 2429 | assert.Equal("resources", fetchedObjects.Results[0].ObjectId) 2430 | assert.Equal(map[string]interface{}{"description": "Helpful documents"}, fetchedObjects.Results[0].Meta) 2431 | 2432 | warrantToken, err := object.BatchDelete([]warrant.ObjectParams{ 2433 | {ObjectType: "document", ObjectId: "document-a"}, 2434 | {ObjectType: "document", ObjectId: "document-b"}, 2435 | {ObjectType: "folder", ObjectId: "resources"}, 2436 | }) 2437 | if err != nil { 2438 | t.Fatal(err) 2439 | } 2440 | assert.NotNil(warrantToken) 2441 | 2442 | fetchedObjects, err = object.ListObjects(&warrant.ListObjectParams{ 2443 | ListParams: warrant.ListParams{ 2444 | RequestOptions: warrant.RequestOptions{ 2445 | WarrantToken: "latest", 2446 | }, 2447 | Limit: 10, 2448 | }, 2449 | }) 2450 | if err != nil { 2451 | t.Fatal(err) 2452 | } 2453 | assert.Len(fetchedObjects.Results, 0) 2454 | } 2455 | -------------------------------------------------------------------------------- /feature.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ObjectTypeFeature = "feature" 4 | 5 | type Feature struct { 6 | FeatureId string `json:"featureId"` 7 | Meta map[string]interface{} `json:"meta,omitempty"` 8 | } 9 | 10 | func (feature Feature) GetObjectType() string { 11 | return "feature" 12 | } 13 | 14 | func (feature Feature) GetObjectId() string { 15 | return feature.FeatureId 16 | } 17 | 18 | type ListFeatureParams struct { 19 | ListParams 20 | } 21 | 22 | type FeatureParams struct { 23 | RequestOptions 24 | FeatureId string `json:"featureId"` 25 | Meta map[string]interface{} `json:"meta,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /feature/client.go: -------------------------------------------------------------------------------- 1 | package feature 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/warrant-dev/warrant-go/v6" 7 | "github.com/warrant-dev/warrant-go/v6/object" 8 | ) 9 | 10 | type Client struct { 11 | apiClient *warrant.ApiClient 12 | } 13 | 14 | func NewClient(config warrant.ClientConfig) Client { 15 | return Client{ 16 | apiClient: warrant.NewApiClient(config), 17 | } 18 | } 19 | 20 | func (c Client) Create(params *warrant.FeatureParams) (*warrant.Feature, error) { 21 | if params == nil { 22 | params = &warrant.FeatureParams{} 23 | } 24 | objectParams := warrant.ObjectParams{ 25 | ObjectType: warrant.ObjectTypeFeature, 26 | RequestOptions: params.RequestOptions, 27 | } 28 | if params.FeatureId != "" { 29 | objectParams.ObjectId = params.FeatureId 30 | } 31 | if params.Meta != nil { 32 | objectParams.Meta = params.Meta 33 | } 34 | object, err := object.Create(&objectParams) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &warrant.Feature{ 39 | FeatureId: object.ObjectId, 40 | Meta: object.Meta, 41 | }, nil 42 | } 43 | 44 | func Create(params *warrant.FeatureParams) (*warrant.Feature, error) { 45 | return getClient().Create(params) 46 | } 47 | 48 | func (c Client) Get(featureId string, params *warrant.FeatureParams) (*warrant.Feature, error) { 49 | if params == nil { 50 | params = &warrant.FeatureParams{} 51 | } 52 | objectParams := warrant.ObjectParams{ 53 | ObjectType: warrant.ObjectTypeFeature, 54 | ObjectId: featureId, 55 | RequestOptions: params.RequestOptions, 56 | Meta: params.Meta, 57 | } 58 | object, err := object.Get(warrant.ObjectTypeFeature, featureId, &objectParams) 59 | if err != nil { 60 | return nil, err 61 | } 62 | return &warrant.Feature{ 63 | FeatureId: object.ObjectId, 64 | Meta: object.Meta, 65 | }, nil 66 | } 67 | 68 | func Get(featureId string, params *warrant.FeatureParams) (*warrant.Feature, error) { 69 | return getClient().Get(featureId, params) 70 | } 71 | 72 | func (c Client) Update(featureId string, params *warrant.FeatureParams) (*warrant.Feature, error) { 73 | if params == nil { 74 | params = &warrant.FeatureParams{} 75 | } 76 | objectParams := warrant.ObjectParams{ 77 | ObjectType: warrant.ObjectTypeFeature, 78 | ObjectId: featureId, 79 | RequestOptions: params.RequestOptions, 80 | Meta: params.Meta, 81 | } 82 | object, err := object.Update(warrant.ObjectTypeFeature, featureId, &objectParams) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return &warrant.Feature{ 87 | FeatureId: object.ObjectId, 88 | Meta: object.Meta, 89 | }, nil 90 | } 91 | 92 | func Update(featureId string, params *warrant.FeatureParams) (*warrant.Feature, error) { 93 | return getClient().Update(featureId, params) 94 | } 95 | 96 | func (c Client) Delete(featureId string) (string, error) { 97 | return object.Delete(warrant.ObjectTypeFeature, featureId) 98 | } 99 | 100 | func Delete(featureId string) (string, error) { 101 | return getClient().Delete(featureId) 102 | } 103 | 104 | func (c Client) ListFeatures(listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 105 | if listParams == nil { 106 | listParams = &warrant.ListFeatureParams{} 107 | } 108 | var featuresListResponse warrant.ListResponse[warrant.Feature] 109 | 110 | objectsListResponse, err := object.ListObjects(&warrant.ListObjectParams{ 111 | ListParams: listParams.ListParams, 112 | ObjectType: warrant.ObjectTypeFeature, 113 | }) 114 | if err != nil { 115 | return featuresListResponse, err 116 | } 117 | 118 | features := make([]warrant.Feature, 0) 119 | for _, object := range objectsListResponse.Results { 120 | features = append(features, warrant.Feature{ 121 | FeatureId: object.ObjectId, 122 | Meta: object.Meta, 123 | }) 124 | } 125 | 126 | featuresListResponse = warrant.ListResponse[warrant.Feature]{ 127 | Results: features, 128 | PrevCursor: objectsListResponse.PrevCursor, 129 | NextCursor: objectsListResponse.NextCursor, 130 | } 131 | 132 | return featuresListResponse, nil 133 | } 134 | 135 | func ListFeatures(listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 136 | return getClient().ListFeatures(listParams) 137 | } 138 | 139 | func (c Client) ListFeaturesForPricingTier(pricingTierId string, listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 140 | if listParams == nil { 141 | listParams = &warrant.ListFeatureParams{} 142 | } 143 | var featuresListResponse warrant.ListResponse[warrant.Feature] 144 | 145 | queryResponse, err := warrant.Query(fmt.Sprintf("select feature where pricing-tier:%s is *", pricingTierId), &warrant.QueryParams{ 146 | ListParams: listParams.ListParams, 147 | }) 148 | if err != nil { 149 | return featuresListResponse, err 150 | } 151 | 152 | features := make([]warrant.Feature, 0) 153 | for _, queryResult := range queryResponse.Results { 154 | features = append(features, warrant.Feature{ 155 | FeatureId: queryResult.ObjectId, 156 | Meta: queryResult.Meta, 157 | }) 158 | } 159 | 160 | featuresListResponse = warrant.ListResponse[warrant.Feature]{ 161 | Results: features, 162 | PrevCursor: queryResponse.PrevCursor, 163 | NextCursor: queryResponse.NextCursor, 164 | } 165 | 166 | return featuresListResponse, nil 167 | } 168 | 169 | func ListFeaturesForPricingTier(pricingTierId string, listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 170 | return getClient().ListFeaturesForPricingTier(pricingTierId, listParams) 171 | } 172 | 173 | func (c Client) AssignFeatureToPricingTier(featureId string, pricingTierId string) (*warrant.Warrant, error) { 174 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 175 | ObjectType: warrant.ObjectTypeFeature, 176 | ObjectId: featureId, 177 | Relation: "member", 178 | Subject: warrant.Subject{ 179 | ObjectType: warrant.ObjectTypePricingTier, 180 | ObjectId: pricingTierId, 181 | }, 182 | }) 183 | } 184 | 185 | func AssignFeatureToPricingTier(featureId string, pricingTierId string) (*warrant.Warrant, error) { 186 | return getClient().AssignFeatureToPricingTier(featureId, pricingTierId) 187 | } 188 | 189 | func (c Client) RemoveFeatureFromPricingTier(featureId string, pricingTierId string) (string, error) { 190 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 191 | ObjectType: warrant.ObjectTypeFeature, 192 | ObjectId: featureId, 193 | Relation: "member", 194 | Subject: warrant.Subject{ 195 | ObjectType: warrant.ObjectTypePricingTier, 196 | ObjectId: pricingTierId, 197 | }, 198 | }) 199 | } 200 | 201 | func RemoveFeatureFromPricingTier(featureId string, pricingTierId string) (string, error) { 202 | return getClient().RemoveFeatureFromPricingTier(featureId, pricingTierId) 203 | } 204 | 205 | func (c Client) ListFeaturesForTenant(tenantId string, listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 206 | if listParams == nil { 207 | listParams = &warrant.ListFeatureParams{} 208 | } 209 | var featuresListResponse warrant.ListResponse[warrant.Feature] 210 | 211 | queryResponse, err := warrant.Query(fmt.Sprintf("select feature where tenant:%s is *", tenantId), &warrant.QueryParams{ 212 | ListParams: listParams.ListParams, 213 | }) 214 | if err != nil { 215 | return featuresListResponse, err 216 | } 217 | 218 | features := make([]warrant.Feature, 0) 219 | for _, queryResult := range queryResponse.Results { 220 | features = append(features, warrant.Feature{ 221 | FeatureId: queryResult.ObjectId, 222 | Meta: queryResult.Meta, 223 | }) 224 | } 225 | 226 | featuresListResponse = warrant.ListResponse[warrant.Feature]{ 227 | Results: features, 228 | PrevCursor: queryResponse.PrevCursor, 229 | NextCursor: queryResponse.NextCursor, 230 | } 231 | 232 | return featuresListResponse, nil 233 | } 234 | 235 | func ListFeaturesForTenant(tenantId string, listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 236 | return getClient().ListFeaturesForTenant(tenantId, listParams) 237 | } 238 | 239 | func (c Client) AssignFeatureToTenant(featureId string, tenantId string) (*warrant.Warrant, error) { 240 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 241 | ObjectType: warrant.ObjectTypeFeature, 242 | ObjectId: featureId, 243 | Relation: "member", 244 | Subject: warrant.Subject{ 245 | ObjectType: warrant.ObjectTypeTenant, 246 | ObjectId: tenantId, 247 | }, 248 | }) 249 | } 250 | 251 | func AssignFeatureToTenant(featureId string, tenantId string) (*warrant.Warrant, error) { 252 | return getClient().AssignFeatureToTenant(featureId, tenantId) 253 | } 254 | 255 | func (c Client) RemoveFeatureFromTenant(featureId string, tenantId string) (string, error) { 256 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 257 | ObjectType: warrant.ObjectTypeFeature, 258 | ObjectId: featureId, 259 | Relation: "member", 260 | Subject: warrant.Subject{ 261 | ObjectType: warrant.ObjectTypeTenant, 262 | ObjectId: tenantId, 263 | }, 264 | }) 265 | } 266 | 267 | func RemoveFeatureFromTenant(featureId string, tenantId string) (string, error) { 268 | return getClient().RemoveFeatureFromTenant(featureId, tenantId) 269 | } 270 | 271 | func (c Client) ListFeaturesForUser(userId string, listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 272 | if listParams == nil { 273 | listParams = &warrant.ListFeatureParams{} 274 | } 275 | var featuresListResponse warrant.ListResponse[warrant.Feature] 276 | 277 | queryResponse, err := warrant.Query(fmt.Sprintf("select feature where user:%s is *", userId), &warrant.QueryParams{ 278 | ListParams: listParams.ListParams, 279 | }) 280 | if err != nil { 281 | return featuresListResponse, err 282 | } 283 | 284 | features := make([]warrant.Feature, 0) 285 | for _, queryResult := range queryResponse.Results { 286 | features = append(features, warrant.Feature{ 287 | FeatureId: queryResult.ObjectId, 288 | Meta: queryResult.Meta, 289 | }) 290 | } 291 | 292 | featuresListResponse = warrant.ListResponse[warrant.Feature]{ 293 | Results: features, 294 | PrevCursor: queryResponse.PrevCursor, 295 | NextCursor: queryResponse.NextCursor, 296 | } 297 | 298 | return featuresListResponse, nil 299 | } 300 | 301 | func ListFeaturesForUser(userId string, listParams *warrant.ListFeatureParams) (warrant.ListResponse[warrant.Feature], error) { 302 | return getClient().ListFeaturesForUser(userId, listParams) 303 | } 304 | 305 | func (c Client) AssignFeatureToUser(featureId string, userId string) (*warrant.Warrant, error) { 306 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 307 | ObjectType: warrant.ObjectTypeFeature, 308 | ObjectId: featureId, 309 | Relation: "member", 310 | Subject: warrant.Subject{ 311 | ObjectType: warrant.ObjectTypeUser, 312 | ObjectId: userId, 313 | }, 314 | }) 315 | } 316 | 317 | func AssignFeatureToUser(featureId string, userId string) (*warrant.Warrant, error) { 318 | return getClient().AssignFeatureToUser(featureId, userId) 319 | } 320 | 321 | func (c Client) RemoveFeatureFromUser(featureId string, userId string) (string, error) { 322 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 323 | ObjectType: warrant.ObjectTypeFeature, 324 | ObjectId: featureId, 325 | Relation: "member", 326 | Subject: warrant.Subject{ 327 | ObjectType: warrant.ObjectTypeUser, 328 | ObjectId: userId, 329 | }, 330 | }) 331 | } 332 | 333 | func RemoveFeatureFromUser(featureId string, userId string) (string, error) { 334 | return getClient().RemoveFeatureFromUser(featureId, userId) 335 | } 336 | 337 | func getClient() Client { 338 | config := warrant.ClientConfig{ 339 | ApiKey: warrant.ApiKey, 340 | ApiEndpoint: warrant.ApiEndpoint, 341 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 342 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 343 | HttpClient: warrant.HttpClient, 344 | } 345 | 346 | return Client{ 347 | &warrant.ApiClient{ 348 | HttpClient: warrant.HttpClient, 349 | Config: config, 350 | }, 351 | } 352 | } 353 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/warrant-dev/warrant-go/v6 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/google/go-querystring v1.1.0 7 | github.com/stretchr/testify v1.9.0 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/pmezard/go-difflib v1.0.0 // indirect 13 | gopkg.in/yaml.v3 v3.0.1 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 4 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 5 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 6 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 10 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 11 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 12 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 14 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 15 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 16 | -------------------------------------------------------------------------------- /list.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | type ListParams struct { 4 | RequestOptions 5 | PrevCursor string `json:"prevCursor,omitempty" url:"prevCursor,omitempty"` 6 | NextCursor string `json:"nextCursor,omitempty" url:"nextCursor,omitempty"` 7 | SortBy string `json:"sortBy,omitempty" url:"sortBy,omitempty"` 8 | SortOrder string `json:"sortOrder,omitempty" url:"sortOrder,omitempty"` 9 | Limit int `json:"limit,omitempty" url:"limit,omitempty"` 10 | } 11 | 12 | type ListResponse[T any] struct { 13 | Results []T `json:"results,omitempty"` 14 | PrevCursor string `json:"prevCursor,omitempty"` 15 | NextCursor string `json:"nextCursor,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /middleware.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | ) 7 | 8 | type GetObjectIdFunc func(r *http.Request) string 9 | 10 | type GetUserIdFunc func(r *http.Request) string 11 | 12 | type NewEnsureIsAuthorizedFunc func(handler http.Handler, options EnsureIsAuthorizedOptions) *EnsureIsAuthorized 13 | 14 | type NewEnsureHasPermissionFunc func(handler http.Handler, options EnsureHasPermissionOptions) *EnsureHasPermission 15 | 16 | type MiddlewareConfig struct { 17 | ApiKey string 18 | GetObjectId GetObjectIdFunc 19 | GetUserId GetUserIdFunc 20 | OnAccessDenied http.HandlerFunc 21 | } 22 | 23 | type Middleware struct { 24 | config MiddlewareConfig 25 | client WarrantClient 26 | } 27 | 28 | type EnsureIsAuthorizedOptions struct { 29 | ObjectType string 30 | ObjectId string 31 | Relation string 32 | UserId string 33 | } 34 | 35 | type EnsureIsAuthorized struct { 36 | handler http.Handler 37 | mw Middleware 38 | options EnsureIsAuthorizedOptions 39 | } 40 | 41 | type EnsureHasPermissionOptions struct { 42 | PermissionId string 43 | UserId string 44 | } 45 | 46 | type EnsureHasPermission struct { 47 | handler http.Handler 48 | mw Middleware 49 | options EnsureHasPermissionOptions 50 | } 51 | 52 | func defaultOnAccessDenied(w http.ResponseWriter, r *http.Request) { 53 | w.WriteHeader(http.StatusUnauthorized) 54 | } 55 | 56 | func (eia *EnsureIsAuthorized) ServeHTTP(w http.ResponseWriter, r *http.Request) { 57 | objectId := eia.options.ObjectId 58 | userId := eia.options.UserId 59 | 60 | if objectId == "" { 61 | objectId = eia.mw.config.GetObjectId(r) 62 | } 63 | 64 | if userId == "" { 65 | userId = eia.mw.config.GetUserId(r) 66 | } 67 | 68 | isAuthorized, err := eia.mw.client.Check(&WarrantCheckParams{ 69 | WarrantCheck: WarrantCheck{ 70 | Object: Object{ 71 | ObjectType: eia.options.ObjectType, 72 | ObjectId: objectId, 73 | }, 74 | Relation: eia.options.Relation, 75 | Subject: Subject{ 76 | ObjectType: ObjectTypeUser, 77 | ObjectId: userId, 78 | }, 79 | }, 80 | }) 81 | if err != nil { 82 | log.Println(err) 83 | eia.mw.config.OnAccessDenied(w, r) 84 | return 85 | } 86 | 87 | if !isAuthorized { 88 | eia.mw.config.OnAccessDenied(w, r) 89 | return 90 | } 91 | 92 | eia.handler.ServeHTTP(w, r) 93 | } 94 | 95 | func (mw Middleware) NewEnsureIsAuthorized(handler http.Handler, options EnsureIsAuthorizedOptions) *EnsureIsAuthorized { 96 | if options.ObjectId == "" && mw.config.GetObjectId == nil { 97 | panic("You must either provide GetObjectId to the Warrant middleware when calling NewMiddleware or provide an ObjectId when calling NewEnsureIsAuthorized.") 98 | } 99 | 100 | if options.UserId == "" && mw.config.GetUserId == nil { 101 | panic("You must either provide GetUserId to the Warrant middleware when calling NewMiddleware or provide a UserId when calling NewEnsureIsAuthorized.") 102 | } 103 | 104 | return &EnsureIsAuthorized{ 105 | handler: handler, 106 | mw: mw, 107 | options: options, 108 | } 109 | } 110 | 111 | func (ehp *EnsureHasPermission) ServeHTTP(w http.ResponseWriter, r *http.Request) { 112 | userId := ehp.options.UserId 113 | if userId == "" { 114 | userId = ehp.mw.config.GetUserId(r) 115 | } 116 | 117 | isAuthorized, err := ehp.mw.client.CheckUserHasPermission(&PermissionCheckParams{ 118 | PermissionId: ehp.options.PermissionId, 119 | UserId: userId, 120 | }) 121 | if err != nil { 122 | log.Println(err) 123 | ehp.mw.config.OnAccessDenied(w, r) 124 | return 125 | } 126 | 127 | if !isAuthorized { 128 | ehp.mw.config.OnAccessDenied(w, r) 129 | return 130 | } 131 | 132 | ehp.handler.ServeHTTP(w, r) 133 | } 134 | 135 | func (mw Middleware) NewEnsureHasPermission(handler http.Handler, options EnsureHasPermissionOptions) *EnsureHasPermission { 136 | return &EnsureHasPermission{ 137 | handler: handler, 138 | mw: mw, 139 | options: options, 140 | } 141 | } 142 | 143 | func NewMiddleware(middlewareConfig MiddlewareConfig) *Middleware { 144 | if middlewareConfig.OnAccessDenied == nil { 145 | middlewareConfig.OnAccessDenied = defaultOnAccessDenied 146 | } 147 | 148 | return &Middleware{ 149 | config: middlewareConfig, 150 | client: NewClient(ClientConfig{ 151 | ApiKey: middlewareConfig.ApiKey, 152 | ApiEndpoint: ApiEndpoint, 153 | AuthorizeEndpoint: AuthorizeEndpoint, 154 | SelfServiceDashEndpoint: SelfServiceDashEndpoint, 155 | }), 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /object/client.go: -------------------------------------------------------------------------------- 1 | package object 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | 8 | "github.com/google/go-querystring/query" 9 | "github.com/warrant-dev/warrant-go/v6" 10 | ) 11 | 12 | type Client struct { 13 | apiClient *warrant.ApiClient 14 | } 15 | 16 | func NewClient(config warrant.ClientConfig) Client { 17 | return Client{ 18 | apiClient: warrant.NewApiClient(config), 19 | } 20 | } 21 | 22 | func (c Client) Create(params *warrant.ObjectParams) (*warrant.Object, error) { 23 | resp, err := c.apiClient.MakeRequest("POST", "/v2/objects", params, &warrant.RequestOptions{}) 24 | if err != nil { 25 | return nil, err 26 | } 27 | body, err := io.ReadAll(resp.Body) 28 | if err != nil { 29 | return nil, warrant.WrapError("Error reading response", err) 30 | } 31 | defer resp.Body.Close() 32 | var newObject warrant.Object 33 | err = json.Unmarshal([]byte(body), &newObject) 34 | if err != nil { 35 | return nil, warrant.WrapError("Invalid response from server", err) 36 | } 37 | return &newObject, nil 38 | } 39 | 40 | func Create(params *warrant.ObjectParams) (*warrant.Object, error) { 41 | return getClient().Create(params) 42 | } 43 | 44 | func (c Client) BatchCreate(params []warrant.ObjectParams) ([]warrant.Object, error) { 45 | resp, err := c.apiClient.MakeRequest("POST", "/v2/objects", params, &warrant.RequestOptions{}) 46 | if err != nil { 47 | return nil, err 48 | } 49 | body, err := io.ReadAll(resp.Body) 50 | if err != nil { 51 | return nil, warrant.WrapError("Error reading response", err) 52 | } 53 | defer resp.Body.Close() 54 | var newObjects []warrant.Object 55 | err = json.Unmarshal([]byte(body), &newObjects) 56 | if err != nil { 57 | return nil, warrant.WrapError("Invalid response from server", err) 58 | } 59 | return newObjects, nil 60 | } 61 | 62 | func BatchCreate(params []warrant.ObjectParams) ([]warrant.Object, error) { 63 | return getClient().BatchCreate(params) 64 | } 65 | 66 | func (c Client) Get(objectType string, objectId string, params *warrant.ObjectParams) (*warrant.Object, error) { 67 | if params == nil { 68 | params = &warrant.ObjectParams{} 69 | } 70 | resp, err := c.apiClient.MakeRequest("GET", fmt.Sprintf("/v2/objects/%s/%s", objectType, objectId), nil, ¶ms.RequestOptions) 71 | if err != nil { 72 | return nil, err 73 | } 74 | body, err := io.ReadAll(resp.Body) 75 | if err != nil { 76 | return nil, warrant.WrapError("Error reading response", err) 77 | } 78 | defer resp.Body.Close() 79 | var foundObject warrant.Object 80 | err = json.Unmarshal([]byte(body), &foundObject) 81 | if err != nil { 82 | return nil, warrant.WrapError("Invalid response from server", err) 83 | } 84 | return &foundObject, nil 85 | } 86 | 87 | func Get(objectType string, objectId string, params *warrant.ObjectParams) (*warrant.Object, error) { 88 | return getClient().Get(objectType, objectId, params) 89 | } 90 | 91 | func (c Client) Update(objectType string, objectId string, params *warrant.ObjectParams) (*warrant.Object, error) { 92 | resp, err := c.apiClient.MakeRequest("PUT", fmt.Sprintf("/v2/objects/%s/%s", objectType, objectId), params, &warrant.RequestOptions{}) 93 | if err != nil { 94 | return nil, err 95 | } 96 | body, err := io.ReadAll(resp.Body) 97 | if err != nil { 98 | return nil, warrant.WrapError("Error reading response", err) 99 | } 100 | defer resp.Body.Close() 101 | var updatedObject warrant.Object 102 | err = json.Unmarshal([]byte(body), &updatedObject) 103 | if err != nil { 104 | return nil, warrant.WrapError("Invalid response from server", err) 105 | } 106 | return &updatedObject, nil 107 | } 108 | 109 | func Update(objectType string, objectId string, params *warrant.ObjectParams) (*warrant.Object, error) { 110 | return getClient().Update(objectType, objectId, params) 111 | } 112 | 113 | func (c Client) Delete(objectType string, objectId string) (string, error) { 114 | resp, err := c.apiClient.MakeRequest("DELETE", fmt.Sprintf("/v2/objects/%s/%s", objectType, objectId), nil, &warrant.RequestOptions{}) 115 | if err != nil { 116 | return "", err 117 | } 118 | defer resp.Body.Close() 119 | warrantToken := resp.Header.Get("Warrant-Token") 120 | return warrantToken, nil 121 | } 122 | 123 | func Delete(objectType string, objectId string) (string, error) { 124 | return getClient().Delete(objectType, objectId) 125 | } 126 | 127 | func (c Client) BatchDelete(params []warrant.ObjectParams) (string, error) { 128 | resp, err := c.apiClient.MakeRequest("DELETE", "/v2/objects", params, &warrant.RequestOptions{}) 129 | if err != nil { 130 | return "", err 131 | } 132 | defer resp.Body.Close() 133 | warrantToken := resp.Header.Get("Warrant-Token") 134 | return warrantToken, nil 135 | } 136 | 137 | func BatchDelete(params []warrant.ObjectParams) (string, error) { 138 | return getClient().BatchDelete(params) 139 | } 140 | 141 | func (c Client) ListObjects(listParams *warrant.ListObjectParams) (warrant.ListResponse[warrant.Object], error) { 142 | if listParams == nil { 143 | listParams = &warrant.ListObjectParams{} 144 | } 145 | var objectsListResponse warrant.ListResponse[warrant.Object] 146 | queryParams, err := query.Values(listParams) 147 | if err != nil { 148 | return objectsListResponse, warrant.WrapError("Could not parse listParams", err) 149 | } 150 | 151 | resp, err := c.apiClient.MakeRequest("GET", fmt.Sprintf("/v2/objects?%s", queryParams.Encode()), objectsListResponse, &listParams.RequestOptions) 152 | if err != nil { 153 | return objectsListResponse, err 154 | } 155 | body, err := io.ReadAll(resp.Body) 156 | if err != nil { 157 | return objectsListResponse, warrant.WrapError("Error reading response", err) 158 | } 159 | defer resp.Body.Close() 160 | err = json.Unmarshal([]byte(body), &objectsListResponse) 161 | if err != nil { 162 | return objectsListResponse, warrant.WrapError("Invalid response from server", err) 163 | } 164 | return objectsListResponse, nil 165 | } 166 | 167 | func ListObjects(listParams *warrant.ListObjectParams) (warrant.ListResponse[warrant.Object], error) { 168 | return getClient().ListObjects(listParams) 169 | } 170 | 171 | func getClient() Client { 172 | config := warrant.ClientConfig{ 173 | ApiKey: warrant.ApiKey, 174 | ApiEndpoint: warrant.ApiEndpoint, 175 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 176 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 177 | HttpClient: warrant.HttpClient, 178 | } 179 | 180 | return Client{ 181 | &warrant.ApiClient{ 182 | HttpClient: warrant.HttpClient, 183 | Config: config, 184 | }, 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /objecttype.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | type ObjectType struct { 4 | Type string `json:"type"` 5 | Relations map[string]interface{} `json:"relations"` 6 | WarrantToken string `json:"warrantToken,omitempty"` 7 | } 8 | 9 | type ListObjectTypeParams struct { 10 | ListParams 11 | } 12 | 13 | type ObjectTypeParams struct { 14 | RequestOptions 15 | Type string `json:"type"` 16 | Relations map[string]interface{} `json:"relations"` 17 | } 18 | -------------------------------------------------------------------------------- /objecttype/client.go: -------------------------------------------------------------------------------- 1 | package objecttype 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | 8 | "github.com/google/go-querystring/query" 9 | "github.com/warrant-dev/warrant-go/v6" 10 | ) 11 | 12 | type Client struct { 13 | apiClient *warrant.ApiClient 14 | } 15 | 16 | func NewClient(config warrant.ClientConfig) Client { 17 | return Client{ 18 | apiClient: warrant.NewApiClient(config), 19 | } 20 | } 21 | 22 | func (c Client) Create(params *warrant.ObjectTypeParams) (*warrant.ObjectType, error) { 23 | resp, err := c.apiClient.MakeRequest("POST", "/v2/object-types", params, &warrant.RequestOptions{}) 24 | if err != nil { 25 | return nil, err 26 | } 27 | body, err := io.ReadAll(resp.Body) 28 | if err != nil { 29 | return nil, warrant.WrapError("Error reading response", err) 30 | } 31 | defer resp.Body.Close() 32 | var newObjectType warrant.ObjectType 33 | err = json.Unmarshal([]byte(body), &newObjectType) 34 | if err != nil { 35 | return nil, warrant.WrapError("Invalid response from server", err) 36 | } 37 | warrantToken := resp.Header.Get("Warrant-Token") 38 | newObjectType.WarrantToken = warrantToken 39 | return &newObjectType, nil 40 | } 41 | 42 | func Create(params *warrant.ObjectTypeParams) (*warrant.ObjectType, error) { 43 | return getClient().Create(params) 44 | } 45 | 46 | func (c Client) Get(objectTypeId string, params *warrant.ObjectTypeParams) (*warrant.ObjectType, error) { 47 | if params == nil { 48 | params = &warrant.ObjectTypeParams{} 49 | } 50 | resp, err := c.apiClient.MakeRequest("GET", fmt.Sprintf("/v2/object-types/%s", objectTypeId), nil, ¶ms.RequestOptions) 51 | if err != nil { 52 | return nil, err 53 | } 54 | body, err := io.ReadAll(resp.Body) 55 | if err != nil { 56 | return nil, warrant.WrapError("Error reading response", err) 57 | } 58 | defer resp.Body.Close() 59 | var foundObjectType warrant.ObjectType 60 | err = json.Unmarshal([]byte(body), &foundObjectType) 61 | if err != nil { 62 | return nil, warrant.WrapError("Invalid response from server", err) 63 | } 64 | return &foundObjectType, nil 65 | } 66 | 67 | func Get(objectTypeId string, params *warrant.ObjectTypeParams) (*warrant.ObjectType, error) { 68 | return getClient().Get(objectTypeId, params) 69 | } 70 | 71 | func (c Client) Update(objectTypeId string, params *warrant.ObjectTypeParams) (*warrant.ObjectType, error) { 72 | resp, err := c.apiClient.MakeRequest("PUT", fmt.Sprintf("/v2/object-types/%s", objectTypeId), params, &warrant.RequestOptions{}) 73 | if err != nil { 74 | return nil, err 75 | } 76 | body, err := io.ReadAll(resp.Body) 77 | if err != nil { 78 | return nil, warrant.WrapError("Error reading response", err) 79 | } 80 | defer resp.Body.Close() 81 | var updatedObjectType warrant.ObjectType 82 | err = json.Unmarshal([]byte(body), &updatedObjectType) 83 | if err != nil { 84 | return nil, warrant.WrapError("Invalid response from server", err) 85 | } 86 | warrantToken := resp.Header.Get("Warrant-Token") 87 | updatedObjectType.WarrantToken = warrantToken 88 | return &updatedObjectType, nil 89 | } 90 | 91 | func Update(objectTypeId string, params *warrant.ObjectTypeParams) (*warrant.ObjectType, error) { 92 | return getClient().Update(objectTypeId, params) 93 | } 94 | 95 | func (c Client) BatchUpdate(params []warrant.ObjectTypeParams) ([]warrant.ObjectType, error) { 96 | resp, err := c.apiClient.MakeRequest("PUT", "/v2/object-types", params, &warrant.RequestOptions{}) 97 | if err != nil { 98 | return nil, err 99 | } 100 | body, err := io.ReadAll(resp.Body) 101 | if err != nil { 102 | return nil, warrant.WrapError("Error reading response", err) 103 | } 104 | defer resp.Body.Close() 105 | var updatedObjectTypes []warrant.ObjectType 106 | err = json.Unmarshal([]byte(body), &updatedObjectTypes) 107 | if err != nil { 108 | return nil, warrant.WrapError("Invalid response from server", err) 109 | } 110 | warrantToken := resp.Header.Get("Warrant-Token") 111 | for i := range updatedObjectTypes { 112 | updatedObjectTypes[i].WarrantToken = warrantToken 113 | } 114 | return updatedObjectTypes, nil 115 | } 116 | 117 | func BatchUpdate(params []warrant.ObjectTypeParams) ([]warrant.ObjectType, error) { 118 | return getClient().BatchUpdate(params) 119 | } 120 | 121 | func (c Client) Delete(objectTypeId string) (string, error) { 122 | resp, err := c.apiClient.MakeRequest("DELETE", fmt.Sprintf("/v2/object-types/%s", objectTypeId), nil, &warrant.RequestOptions{}) 123 | if err != nil { 124 | return "", err 125 | } 126 | defer resp.Body.Close() 127 | warrantToken := resp.Header.Get("Warrant-Token") 128 | return warrantToken, nil 129 | } 130 | 131 | func Delete(objectTypeId string) (string, error) { 132 | return getClient().Delete(objectTypeId) 133 | } 134 | 135 | func (c Client) ListObjectTypes(listParams *warrant.ListObjectTypeParams) (warrant.ListResponse[warrant.ObjectType], error) { 136 | if listParams == nil { 137 | listParams = &warrant.ListObjectTypeParams{} 138 | } 139 | var objectTypesListResponse warrant.ListResponse[warrant.ObjectType] 140 | queryParams, err := query.Values(listParams) 141 | if err != nil { 142 | return objectTypesListResponse, warrant.WrapError("Could not parse listParams", err) 143 | } 144 | 145 | resp, err := c.apiClient.MakeRequest("GET", fmt.Sprintf("/v2/object-types?%s", queryParams.Encode()), objectTypesListResponse, &listParams.RequestOptions) 146 | if err != nil { 147 | return objectTypesListResponse, err 148 | } 149 | body, err := io.ReadAll(resp.Body) 150 | if err != nil { 151 | return objectTypesListResponse, warrant.WrapError("Error reading response", err) 152 | } 153 | defer resp.Body.Close() 154 | err = json.Unmarshal([]byte(body), &objectTypesListResponse) 155 | if err != nil { 156 | return objectTypesListResponse, warrant.WrapError("Invalid response from server", err) 157 | } 158 | return objectTypesListResponse, nil 159 | } 160 | 161 | func ListObjectTypes(listParams *warrant.ListObjectTypeParams) (warrant.ListResponse[warrant.ObjectType], error) { 162 | return getClient().ListObjectTypes(listParams) 163 | } 164 | 165 | func getClient() Client { 166 | config := warrant.ClientConfig{ 167 | ApiKey: warrant.ApiKey, 168 | ApiEndpoint: warrant.ApiEndpoint, 169 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 170 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 171 | HttpClient: warrant.HttpClient, 172 | } 173 | 174 | return Client{ 175 | &warrant.ApiClient{ 176 | HttpClient: warrant.HttpClient, 177 | Config: config, 178 | }, 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /params.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | type RequestOptions struct { 4 | WarrantToken string `json:"warrantToken,omitempty" url:"warrantToken,omitempty"` 5 | } 6 | 7 | func (requestOptions *RequestOptions) SetWarrantToken(token string) { 8 | requestOptions.WarrantToken = token 9 | } 10 | -------------------------------------------------------------------------------- /permission.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ObjectTypePermission = "permission" 4 | 5 | type Permission struct { 6 | PermissionId string `json:"permissionId"` 7 | Meta map[string]interface{} `json:"meta,omitempty"` 8 | } 9 | 10 | func (permission Permission) GetObjectType() string { 11 | return "permission" 12 | } 13 | 14 | func (permission Permission) GetObjectId() string { 15 | return permission.PermissionId 16 | } 17 | 18 | type ListPermissionParams struct { 19 | ListParams 20 | } 21 | 22 | type PermissionParams struct { 23 | RequestOptions 24 | PermissionId string `json:"permissionId"` 25 | Meta map[string]interface{} `json:"meta,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /permission/client.go: -------------------------------------------------------------------------------- 1 | package permission 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/warrant-dev/warrant-go/v6" 7 | "github.com/warrant-dev/warrant-go/v6/object" 8 | ) 9 | 10 | type Client struct { 11 | apiClient *warrant.ApiClient 12 | } 13 | 14 | func NewClient(config warrant.ClientConfig) Client { 15 | return Client{ 16 | apiClient: warrant.NewApiClient(config), 17 | } 18 | } 19 | 20 | func (c Client) Create(params *warrant.PermissionParams) (*warrant.Permission, error) { 21 | if params == nil { 22 | params = &warrant.PermissionParams{} 23 | } 24 | objectParams := warrant.ObjectParams{ 25 | ObjectType: warrant.ObjectTypePermission, 26 | RequestOptions: params.RequestOptions, 27 | } 28 | if params.PermissionId != "" { 29 | objectParams.ObjectId = params.PermissionId 30 | } 31 | if params.Meta != nil { 32 | objectParams.Meta = params.Meta 33 | } 34 | object, err := object.Create(&objectParams) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &warrant.Permission{ 39 | PermissionId: object.ObjectId, 40 | Meta: object.Meta, 41 | }, nil 42 | } 43 | 44 | func Create(params *warrant.PermissionParams) (*warrant.Permission, error) { 45 | return getClient().Create(params) 46 | } 47 | 48 | func (c Client) Get(permissionId string, params *warrant.PermissionParams) (*warrant.Permission, error) { 49 | if params == nil { 50 | params = &warrant.PermissionParams{} 51 | } 52 | objectParams := warrant.ObjectParams{ 53 | ObjectType: warrant.ObjectTypePermission, 54 | ObjectId: permissionId, 55 | RequestOptions: params.RequestOptions, 56 | Meta: params.Meta, 57 | } 58 | object, err := object.Get(warrant.ObjectTypePermission, permissionId, &objectParams) 59 | if err != nil { 60 | return nil, err 61 | } 62 | return &warrant.Permission{ 63 | PermissionId: object.ObjectId, 64 | Meta: object.Meta, 65 | }, nil 66 | } 67 | 68 | func Get(permissionId string, params *warrant.PermissionParams) (*warrant.Permission, error) { 69 | return getClient().Get(permissionId, params) 70 | } 71 | 72 | func (c Client) Update(permissionId string, params *warrant.PermissionParams) (*warrant.Permission, error) { 73 | if params == nil { 74 | params = &warrant.PermissionParams{} 75 | } 76 | objectParams := warrant.ObjectParams{ 77 | ObjectType: warrant.ObjectTypePermission, 78 | ObjectId: permissionId, 79 | RequestOptions: params.RequestOptions, 80 | Meta: params.Meta, 81 | } 82 | object, err := object.Update(warrant.ObjectTypePermission, permissionId, &objectParams) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return &warrant.Permission{ 87 | PermissionId: object.ObjectId, 88 | Meta: object.Meta, 89 | }, nil 90 | } 91 | 92 | func Update(permissionId string, params *warrant.PermissionParams) (*warrant.Permission, error) { 93 | return getClient().Update(permissionId, params) 94 | } 95 | 96 | func (c Client) Delete(permissionId string) (string, error) { 97 | return object.Delete(warrant.ObjectTypePermission, permissionId) 98 | } 99 | 100 | func Delete(permissionId string) (string, error) { 101 | return getClient().Delete(permissionId) 102 | } 103 | 104 | func (c Client) ListPermissions(listParams *warrant.ListPermissionParams) (warrant.ListResponse[warrant.Permission], error) { 105 | if listParams == nil { 106 | listParams = &warrant.ListPermissionParams{} 107 | } 108 | var permissionsListResponse warrant.ListResponse[warrant.Permission] 109 | 110 | objectsListResponse, err := object.ListObjects(&warrant.ListObjectParams{ 111 | ListParams: listParams.ListParams, 112 | ObjectType: warrant.ObjectTypePermission, 113 | }) 114 | if err != nil { 115 | return permissionsListResponse, err 116 | } 117 | 118 | permissions := make([]warrant.Permission, 0) 119 | for _, object := range objectsListResponse.Results { 120 | permissions = append(permissions, warrant.Permission{ 121 | PermissionId: object.ObjectId, 122 | Meta: object.Meta, 123 | }) 124 | } 125 | 126 | permissionsListResponse = warrant.ListResponse[warrant.Permission]{ 127 | Results: permissions, 128 | PrevCursor: objectsListResponse.PrevCursor, 129 | NextCursor: objectsListResponse.NextCursor, 130 | } 131 | 132 | return permissionsListResponse, nil 133 | } 134 | 135 | func ListPermissions(listParams *warrant.ListPermissionParams) (warrant.ListResponse[warrant.Permission], error) { 136 | return getClient().ListPermissions(listParams) 137 | } 138 | 139 | func (c Client) ListPermissionsForRole(roleId string, listParams *warrant.ListPermissionParams) (warrant.ListResponse[warrant.Permission], error) { 140 | if listParams == nil { 141 | listParams = &warrant.ListPermissionParams{} 142 | } 143 | var permissionsListResponse warrant.ListResponse[warrant.Permission] 144 | 145 | queryResponse, err := warrant.Query(fmt.Sprintf("select permission where role:%s is *", roleId), &warrant.QueryParams{ 146 | ListParams: listParams.ListParams, 147 | }) 148 | if err != nil { 149 | return permissionsListResponse, err 150 | } 151 | 152 | permissions := make([]warrant.Permission, 0) 153 | for _, queryResult := range queryResponse.Results { 154 | permissions = append(permissions, warrant.Permission{ 155 | PermissionId: queryResult.ObjectId, 156 | Meta: queryResult.Meta, 157 | }) 158 | } 159 | 160 | permissionsListResponse = warrant.ListResponse[warrant.Permission]{ 161 | Results: permissions, 162 | PrevCursor: queryResponse.PrevCursor, 163 | NextCursor: queryResponse.NextCursor, 164 | } 165 | 166 | return permissionsListResponse, nil 167 | } 168 | 169 | func ListPermissionsForRole(roleId string, listParams *warrant.ListPermissionParams) (warrant.ListResponse[warrant.Permission], error) { 170 | return getClient().ListPermissionsForRole(roleId, listParams) 171 | } 172 | 173 | func (c Client) AssignPermissionToRole(permissionId string, roleId string) (*warrant.Warrant, error) { 174 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 175 | ObjectType: warrant.ObjectTypePermission, 176 | ObjectId: permissionId, 177 | Relation: "member", 178 | Subject: warrant.Subject{ 179 | ObjectType: warrant.ObjectTypeRole, 180 | ObjectId: roleId, 181 | }, 182 | }) 183 | } 184 | 185 | func AssignPermissionToRole(permissionId string, roleId string) (*warrant.Warrant, error) { 186 | return getClient().AssignPermissionToRole(permissionId, roleId) 187 | } 188 | 189 | func (c Client) RemovePermissionFromRole(permissionId string, roleId string) (string, error) { 190 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 191 | ObjectType: warrant.ObjectTypePermission, 192 | ObjectId: permissionId, 193 | Relation: "member", 194 | Subject: warrant.Subject{ 195 | ObjectType: warrant.ObjectTypeRole, 196 | ObjectId: roleId, 197 | }, 198 | }) 199 | } 200 | 201 | func RemovePermissionFromRole(permissionId string, roleId string) (string, error) { 202 | return getClient().RemovePermissionFromRole(permissionId, roleId) 203 | } 204 | 205 | func (c Client) ListPermissionsForUser(userId string, listParams *warrant.ListPermissionParams) (warrant.ListResponse[warrant.Permission], error) { 206 | if listParams == nil { 207 | listParams = &warrant.ListPermissionParams{} 208 | } 209 | var permissionsListResponse warrant.ListResponse[warrant.Permission] 210 | 211 | queryResponse, err := warrant.Query(fmt.Sprintf("select permission where user:%s is *", userId), &warrant.QueryParams{ 212 | ListParams: listParams.ListParams, 213 | }) 214 | if err != nil { 215 | return permissionsListResponse, err 216 | } 217 | 218 | permissions := make([]warrant.Permission, 0) 219 | for _, queryResult := range queryResponse.Results { 220 | permissions = append(permissions, warrant.Permission{ 221 | PermissionId: queryResult.ObjectId, 222 | Meta: queryResult.Meta, 223 | }) 224 | } 225 | 226 | permissionsListResponse = warrant.ListResponse[warrant.Permission]{ 227 | Results: permissions, 228 | PrevCursor: queryResponse.PrevCursor, 229 | NextCursor: queryResponse.NextCursor, 230 | } 231 | 232 | return permissionsListResponse, nil 233 | } 234 | 235 | func ListPermissionsForUser(userId string, listParams *warrant.ListPermissionParams) (warrant.ListResponse[warrant.Permission], error) { 236 | return getClient().ListPermissionsForUser(userId, listParams) 237 | } 238 | 239 | func (c Client) AssignPermissionToUser(permissionId string, userId string) (*warrant.Warrant, error) { 240 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 241 | ObjectType: warrant.ObjectTypePermission, 242 | ObjectId: permissionId, 243 | Relation: "member", 244 | Subject: warrant.Subject{ 245 | ObjectType: warrant.ObjectTypeUser, 246 | ObjectId: userId, 247 | }, 248 | }) 249 | } 250 | 251 | func AssignPermissionToUser(permissionId string, userId string) (*warrant.Warrant, error) { 252 | return getClient().AssignPermissionToUser(permissionId, userId) 253 | } 254 | 255 | func (c Client) RemovePermissionFromUser(permissionId string, userId string) (string, error) { 256 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 257 | ObjectType: warrant.ObjectTypePermission, 258 | ObjectId: permissionId, 259 | Relation: "member", 260 | Subject: warrant.Subject{ 261 | ObjectType: warrant.ObjectTypeUser, 262 | ObjectId: userId, 263 | }, 264 | }) 265 | } 266 | 267 | func RemovePermissionFromUser(permissionId string, userId string) (string, error) { 268 | return getClient().RemovePermissionFromUser(permissionId, userId) 269 | } 270 | 271 | func getClient() Client { 272 | config := warrant.ClientConfig{ 273 | ApiKey: warrant.ApiKey, 274 | ApiEndpoint: warrant.ApiEndpoint, 275 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 276 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 277 | HttpClient: warrant.HttpClient, 278 | } 279 | 280 | return Client{ 281 | &warrant.ApiClient{ 282 | HttpClient: warrant.HttpClient, 283 | Config: config, 284 | }, 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /pricingtier.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ObjectTypePricingTier = "pricing-tier" 4 | 5 | type PricingTier struct { 6 | PricingTierId string `json:"pricingTierId"` 7 | Meta map[string]interface{} `json:"meta,omitempty"` 8 | } 9 | 10 | func (pricingTier PricingTier) GetObjectType() string { 11 | return "pricing-tier" 12 | } 13 | 14 | func (pricingTier PricingTier) GetObjectId() string { 15 | return pricingTier.PricingTierId 16 | } 17 | 18 | type ListPricingTierParams struct { 19 | ListParams 20 | } 21 | 22 | type PricingTierParams struct { 23 | RequestOptions 24 | PricingTierId string `json:"pricingTierId"` 25 | Meta map[string]interface{} `json:"meta,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /pricingtier/client.go: -------------------------------------------------------------------------------- 1 | package pricingtier 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/warrant-dev/warrant-go/v6" 7 | "github.com/warrant-dev/warrant-go/v6/object" 8 | ) 9 | 10 | type Client struct { 11 | apiClient *warrant.ApiClient 12 | } 13 | 14 | func NewClient(config warrant.ClientConfig) Client { 15 | return Client{ 16 | apiClient: warrant.NewApiClient(config), 17 | } 18 | } 19 | 20 | func (c Client) Create(params *warrant.PricingTierParams) (*warrant.PricingTier, error) { 21 | if params == nil { 22 | params = &warrant.PricingTierParams{} 23 | } 24 | objectParams := warrant.ObjectParams{ 25 | ObjectType: warrant.ObjectTypePricingTier, 26 | RequestOptions: params.RequestOptions, 27 | } 28 | if params.PricingTierId != "" { 29 | objectParams.ObjectId = params.PricingTierId 30 | } 31 | if params.Meta != nil { 32 | objectParams.Meta = params.Meta 33 | } 34 | object, err := object.Create(&objectParams) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &warrant.PricingTier{ 39 | PricingTierId: object.ObjectId, 40 | Meta: object.Meta, 41 | }, nil 42 | } 43 | 44 | func Create(params *warrant.PricingTierParams) (*warrant.PricingTier, error) { 45 | return getClient().Create(params) 46 | } 47 | 48 | func (c Client) Get(pricingTierId string, params *warrant.PricingTierParams) (*warrant.PricingTier, error) { 49 | if params == nil { 50 | params = &warrant.PricingTierParams{} 51 | } 52 | objectParams := warrant.ObjectParams{ 53 | ObjectType: warrant.ObjectTypePricingTier, 54 | ObjectId: pricingTierId, 55 | RequestOptions: params.RequestOptions, 56 | Meta: params.Meta, 57 | } 58 | object, err := object.Get(warrant.ObjectTypePricingTier, pricingTierId, &objectParams) 59 | if err != nil { 60 | return nil, err 61 | } 62 | return &warrant.PricingTier{ 63 | PricingTierId: object.ObjectId, 64 | Meta: object.Meta, 65 | }, nil 66 | } 67 | 68 | func Get(pricingTierId string, params *warrant.PricingTierParams) (*warrant.PricingTier, error) { 69 | return getClient().Get(pricingTierId, params) 70 | } 71 | 72 | func (c Client) Update(pricingTierId string, params *warrant.PricingTierParams) (*warrant.PricingTier, error) { 73 | if params == nil { 74 | params = &warrant.PricingTierParams{} 75 | } 76 | objectParams := warrant.ObjectParams{ 77 | ObjectType: warrant.ObjectTypePricingTier, 78 | ObjectId: pricingTierId, 79 | RequestOptions: params.RequestOptions, 80 | Meta: params.Meta, 81 | } 82 | object, err := object.Update(warrant.ObjectTypePricingTier, pricingTierId, &objectParams) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return &warrant.PricingTier{ 87 | PricingTierId: object.ObjectId, 88 | Meta: object.Meta, 89 | }, nil 90 | } 91 | 92 | func Update(pricingTierId string, params *warrant.PricingTierParams) (*warrant.PricingTier, error) { 93 | return getClient().Update(pricingTierId, params) 94 | } 95 | 96 | func (c Client) Delete(pricingTierId string) (string, error) { 97 | return object.Delete(warrant.ObjectTypePricingTier, pricingTierId) 98 | } 99 | 100 | func Delete(pricingTierId string) (string, error) { 101 | return getClient().Delete(pricingTierId) 102 | } 103 | 104 | func (c Client) ListPricingTiers(listParams *warrant.ListPricingTierParams) (warrant.ListResponse[warrant.PricingTier], error) { 105 | if listParams == nil { 106 | listParams = &warrant.ListPricingTierParams{} 107 | } 108 | var pricingTiersListResponse warrant.ListResponse[warrant.PricingTier] 109 | 110 | objectsListResponse, err := object.ListObjects(&warrant.ListObjectParams{ 111 | ListParams: listParams.ListParams, 112 | ObjectType: warrant.ObjectTypePricingTier, 113 | }) 114 | if err != nil { 115 | return pricingTiersListResponse, err 116 | } 117 | 118 | users := make([]warrant.PricingTier, 0) 119 | for _, object := range objectsListResponse.Results { 120 | users = append(users, warrant.PricingTier{ 121 | PricingTierId: object.ObjectId, 122 | Meta: object.Meta, 123 | }) 124 | } 125 | 126 | pricingTiersListResponse = warrant.ListResponse[warrant.PricingTier]{ 127 | Results: users, 128 | PrevCursor: objectsListResponse.PrevCursor, 129 | NextCursor: objectsListResponse.NextCursor, 130 | } 131 | 132 | return pricingTiersListResponse, nil 133 | } 134 | 135 | func ListPricingTiers(listParams *warrant.ListPricingTierParams) (warrant.ListResponse[warrant.PricingTier], error) { 136 | return getClient().ListPricingTiers(listParams) 137 | } 138 | 139 | func (c Client) ListPricingTiersForTenant(tenantId string, listParams *warrant.ListPricingTierParams) (warrant.ListResponse[warrant.PricingTier], error) { 140 | if listParams == nil { 141 | listParams = &warrant.ListPricingTierParams{} 142 | } 143 | var pricingTiersListResponse warrant.ListResponse[warrant.PricingTier] 144 | 145 | queryResponse, err := warrant.Query(fmt.Sprintf("select pricing-tier where tenant:%s is *", tenantId), &warrant.QueryParams{ 146 | ListParams: listParams.ListParams, 147 | }) 148 | if err != nil { 149 | return pricingTiersListResponse, err 150 | } 151 | 152 | users := make([]warrant.PricingTier, 0) 153 | for _, queryResult := range queryResponse.Results { 154 | users = append(users, warrant.PricingTier{ 155 | PricingTierId: queryResult.ObjectId, 156 | Meta: queryResult.Meta, 157 | }) 158 | } 159 | 160 | pricingTiersListResponse = warrant.ListResponse[warrant.PricingTier]{ 161 | Results: users, 162 | PrevCursor: queryResponse.PrevCursor, 163 | NextCursor: queryResponse.NextCursor, 164 | } 165 | 166 | return pricingTiersListResponse, nil 167 | } 168 | 169 | func ListPricingTiersForTenant(userId string, listParams *warrant.ListPricingTierParams) (warrant.ListResponse[warrant.PricingTier], error) { 170 | return getClient().ListPricingTiersForTenant(userId, listParams) 171 | } 172 | 173 | func (c Client) AssignPricingTierToTenant(pricingTierId string, tenantId string) (*warrant.Warrant, error) { 174 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 175 | ObjectType: warrant.ObjectTypePricingTier, 176 | ObjectId: pricingTierId, 177 | Relation: "member", 178 | Subject: warrant.Subject{ 179 | ObjectType: warrant.ObjectTypeTenant, 180 | ObjectId: tenantId, 181 | }, 182 | }) 183 | } 184 | 185 | func AssignPricingTierToTenant(pricingTierId string, tenantId string) (*warrant.Warrant, error) { 186 | return getClient().AssignPricingTierToTenant(pricingTierId, tenantId) 187 | } 188 | 189 | func (c Client) RemovePricingTierFromTenant(pricingTierId string, tenantId string) (string, error) { 190 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 191 | ObjectType: warrant.ObjectTypePricingTier, 192 | ObjectId: pricingTierId, 193 | Relation: "member", 194 | Subject: warrant.Subject{ 195 | ObjectType: warrant.ObjectTypeTenant, 196 | ObjectId: tenantId, 197 | }, 198 | }) 199 | } 200 | 201 | func RemovePricingTierFromTenant(pricingTierId string, tenantId string) (string, error) { 202 | return getClient().RemovePricingTierFromTenant(pricingTierId, tenantId) 203 | } 204 | 205 | func (c Client) ListPricingTiersForUser(userId string, listParams *warrant.ListPricingTierParams) (warrant.ListResponse[warrant.PricingTier], error) { 206 | if listParams == nil { 207 | listParams = &warrant.ListPricingTierParams{} 208 | } 209 | var pricingTiersListResponse warrant.ListResponse[warrant.PricingTier] 210 | 211 | queryResponse, err := warrant.Query(fmt.Sprintf("select pricing-tier where user:%s is *", userId), &warrant.QueryParams{ 212 | ListParams: listParams.ListParams, 213 | }) 214 | if err != nil { 215 | return pricingTiersListResponse, err 216 | } 217 | 218 | users := make([]warrant.PricingTier, 0) 219 | for _, queryResult := range queryResponse.Results { 220 | users = append(users, warrant.PricingTier{ 221 | PricingTierId: queryResult.ObjectId, 222 | Meta: queryResult.Meta, 223 | }) 224 | } 225 | 226 | pricingTiersListResponse = warrant.ListResponse[warrant.PricingTier]{ 227 | Results: users, 228 | PrevCursor: queryResponse.PrevCursor, 229 | NextCursor: queryResponse.NextCursor, 230 | } 231 | 232 | return pricingTiersListResponse, nil 233 | } 234 | 235 | func ListPricingTiersForUser(userId string, listParams *warrant.ListPricingTierParams) (warrant.ListResponse[warrant.PricingTier], error) { 236 | return getClient().ListPricingTiersForUser(userId, listParams) 237 | } 238 | 239 | func (c Client) AssignPricingTierToUser(pricingTierId string, userId string) (*warrant.Warrant, error) { 240 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 241 | ObjectType: warrant.ObjectTypePricingTier, 242 | ObjectId: pricingTierId, 243 | Relation: "member", 244 | Subject: warrant.Subject{ 245 | ObjectType: warrant.ObjectTypeUser, 246 | ObjectId: userId, 247 | }, 248 | }) 249 | } 250 | 251 | func AssignPricingTierToUser(pricingTierId string, userId string) (*warrant.Warrant, error) { 252 | return getClient().AssignPricingTierToUser(pricingTierId, userId) 253 | } 254 | 255 | func (c Client) RemovePricingTierFromUser(pricingTierId string, userId string) (string, error) { 256 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 257 | ObjectType: warrant.ObjectTypePricingTier, 258 | ObjectId: pricingTierId, 259 | Relation: "member", 260 | Subject: warrant.Subject{ 261 | ObjectType: warrant.ObjectTypeUser, 262 | ObjectId: userId, 263 | }, 264 | }) 265 | } 266 | 267 | func RemovePricingTierFromUser(pricingTierId string, userId string) (string, error) { 268 | return getClient().RemovePricingTierFromUser(pricingTierId, userId) 269 | } 270 | 271 | func getClient() Client { 272 | config := warrant.ClientConfig{ 273 | ApiKey: warrant.ApiKey, 274 | ApiEndpoint: warrant.ApiEndpoint, 275 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 276 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 277 | HttpClient: warrant.HttpClient, 278 | } 279 | 280 | return Client{ 281 | &warrant.ApiClient{ 282 | HttpClient: warrant.HttpClient, 283 | Config: config, 284 | }, 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /query.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | type QueryParams struct { 4 | ListParams 5 | } 6 | 7 | type QueryResponse struct { 8 | Results []QueryResult `json:"results"` 9 | LastId *string `json:"lastId,omitempty"` 10 | } 11 | 12 | type QueryResult struct { 13 | ObjectType string `json:"objectType"` 14 | ObjectId string `json:"objectId"` 15 | Relation string `json:"relation"` 16 | Warrant Warrant `json:"warrant"` 17 | IsImplicit bool `json:"isImplicit"` 18 | Meta map[string]interface{} `json:"meta"` 19 | } 20 | -------------------------------------------------------------------------------- /role.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ObjectTypeRole = "role" 4 | 5 | type Role struct { 6 | RoleId string `json:"roleId"` 7 | Meta map[string]interface{} `json:"meta,omitempty"` 8 | } 9 | 10 | func (role Role) GetObjectType() string { 11 | return "role" 12 | } 13 | 14 | func (role Role) GetObjectId() string { 15 | return role.RoleId 16 | } 17 | 18 | type ListRoleParams struct { 19 | ListParams 20 | } 21 | 22 | type RoleParams struct { 23 | RequestOptions 24 | RoleId string `json:"roleId"` 25 | Meta map[string]interface{} `json:"meta,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /role/client.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/warrant-dev/warrant-go/v6" 7 | "github.com/warrant-dev/warrant-go/v6/object" 8 | ) 9 | 10 | type Client struct { 11 | apiClient *warrant.ApiClient 12 | } 13 | 14 | func NewClient(config warrant.ClientConfig) Client { 15 | return Client{ 16 | apiClient: warrant.NewApiClient(config), 17 | } 18 | } 19 | 20 | func (c Client) Create(params *warrant.RoleParams) (*warrant.Role, error) { 21 | if params == nil { 22 | params = &warrant.RoleParams{} 23 | } 24 | objectParams := warrant.ObjectParams{ 25 | ObjectType: warrant.ObjectTypeRole, 26 | RequestOptions: params.RequestOptions, 27 | } 28 | if params.RoleId != "" { 29 | objectParams.ObjectId = params.RoleId 30 | } 31 | if params.Meta != nil { 32 | objectParams.Meta = params.Meta 33 | } 34 | object, err := object.Create(&objectParams) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &warrant.Role{ 39 | RoleId: object.ObjectId, 40 | Meta: object.Meta, 41 | }, nil 42 | } 43 | 44 | func Create(params *warrant.RoleParams) (*warrant.Role, error) { 45 | return getClient().Create(params) 46 | } 47 | 48 | func (c Client) Get(roleId string, params *warrant.RoleParams) (*warrant.Role, error) { 49 | if params == nil { 50 | params = &warrant.RoleParams{} 51 | } 52 | objectParams := warrant.ObjectParams{ 53 | ObjectType: warrant.ObjectTypeRole, 54 | ObjectId: roleId, 55 | RequestOptions: params.RequestOptions, 56 | Meta: params.Meta, 57 | } 58 | object, err := object.Get(warrant.ObjectTypeRole, roleId, &objectParams) 59 | if err != nil { 60 | return nil, err 61 | } 62 | return &warrant.Role{ 63 | RoleId: object.ObjectId, 64 | Meta: object.Meta, 65 | }, nil 66 | } 67 | 68 | func Get(roleId string, params *warrant.RoleParams) (*warrant.Role, error) { 69 | return getClient().Get(roleId, params) 70 | } 71 | 72 | func (c Client) Update(roleId string, params *warrant.RoleParams) (*warrant.Role, error) { 73 | if params == nil { 74 | params = &warrant.RoleParams{} 75 | } 76 | objectParams := warrant.ObjectParams{ 77 | ObjectType: warrant.ObjectTypeRole, 78 | ObjectId: roleId, 79 | RequestOptions: params.RequestOptions, 80 | Meta: params.Meta, 81 | } 82 | object, err := object.Update(warrant.ObjectTypeRole, roleId, &objectParams) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return &warrant.Role{ 87 | RoleId: object.ObjectId, 88 | Meta: object.Meta, 89 | }, nil 90 | } 91 | 92 | func Update(roleId string, params *warrant.RoleParams) (*warrant.Role, error) { 93 | return getClient().Update(roleId, params) 94 | } 95 | 96 | func (c Client) Delete(roleId string) (string, error) { 97 | return object.Delete(warrant.ObjectTypeRole, roleId) 98 | } 99 | 100 | func Delete(roleId string) (string, error) { 101 | return getClient().Delete(roleId) 102 | } 103 | 104 | func (c Client) ListRoles(listParams *warrant.ListRoleParams) (warrant.ListResponse[warrant.Role], error) { 105 | if listParams == nil { 106 | listParams = &warrant.ListRoleParams{} 107 | } 108 | var rolesListResponse warrant.ListResponse[warrant.Role] 109 | 110 | objectsListResponse, err := object.ListObjects(&warrant.ListObjectParams{ 111 | ListParams: listParams.ListParams, 112 | ObjectType: warrant.ObjectTypeRole, 113 | }) 114 | if err != nil { 115 | return rolesListResponse, err 116 | } 117 | 118 | roles := make([]warrant.Role, 0) 119 | for _, object := range objectsListResponse.Results { 120 | roles = append(roles, warrant.Role{ 121 | RoleId: object.ObjectId, 122 | Meta: object.Meta, 123 | }) 124 | } 125 | 126 | rolesListResponse = warrant.ListResponse[warrant.Role]{ 127 | Results: roles, 128 | PrevCursor: objectsListResponse.PrevCursor, 129 | NextCursor: objectsListResponse.NextCursor, 130 | } 131 | 132 | return rolesListResponse, nil 133 | } 134 | 135 | func ListRoles(listParams *warrant.ListRoleParams) (warrant.ListResponse[warrant.Role], error) { 136 | return getClient().ListRoles(listParams) 137 | } 138 | 139 | func (c Client) ListRolesForUser(userId string, listParams *warrant.ListRoleParams) (warrant.ListResponse[warrant.Role], error) { 140 | if listParams == nil { 141 | listParams = &warrant.ListRoleParams{} 142 | } 143 | var rolesListResponse warrant.ListResponse[warrant.Role] 144 | 145 | queryResponse, err := warrant.Query(fmt.Sprintf("select role where user:%s is *", userId), &warrant.QueryParams{ 146 | ListParams: listParams.ListParams, 147 | }) 148 | if err != nil { 149 | return rolesListResponse, err 150 | } 151 | 152 | users := make([]warrant.Role, 0) 153 | for _, queryResult := range queryResponse.Results { 154 | users = append(users, warrant.Role{ 155 | RoleId: queryResult.ObjectId, 156 | Meta: queryResult.Meta, 157 | }) 158 | } 159 | 160 | rolesListResponse = warrant.ListResponse[warrant.Role]{ 161 | Results: users, 162 | PrevCursor: queryResponse.PrevCursor, 163 | NextCursor: queryResponse.NextCursor, 164 | } 165 | 166 | return rolesListResponse, nil 167 | } 168 | 169 | func ListRolesForUser(userId string, listParams *warrant.ListRoleParams) (warrant.ListResponse[warrant.Role], error) { 170 | return getClient().ListRolesForUser(userId, listParams) 171 | } 172 | 173 | func (c Client) AssignRoleToUser(roleId string, userId string) (*warrant.Warrant, error) { 174 | return warrant.NewClient(c.apiClient.Config).Create(&warrant.WarrantParams{ 175 | ObjectType: warrant.ObjectTypeRole, 176 | ObjectId: roleId, 177 | Relation: "member", 178 | Subject: warrant.Subject{ 179 | ObjectType: warrant.ObjectTypeUser, 180 | ObjectId: userId, 181 | }, 182 | }) 183 | } 184 | 185 | func AssignRoleToUser(roleId string, userId string) (*warrant.Warrant, error) { 186 | return getClient().AssignRoleToUser(roleId, userId) 187 | } 188 | 189 | func (c Client) RemoveRoleFromUser(roleId string, userId string) (string, error) { 190 | return warrant.NewClient(c.apiClient.Config).Delete(&warrant.WarrantParams{ 191 | ObjectType: warrant.ObjectTypeRole, 192 | ObjectId: roleId, 193 | Relation: "member", 194 | Subject: warrant.Subject{ 195 | ObjectType: warrant.ObjectTypeUser, 196 | ObjectId: userId, 197 | }, 198 | }) 199 | } 200 | 201 | func RemoveRoleFromUser(roleId string, userId string) (string, error) { 202 | return getClient().RemoveRoleFromUser(roleId, userId) 203 | } 204 | 205 | func getClient() Client { 206 | config := warrant.ClientConfig{ 207 | ApiKey: warrant.ApiKey, 208 | ApiEndpoint: warrant.ApiEndpoint, 209 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 210 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 211 | HttpClient: warrant.HttpClient, 212 | } 213 | 214 | return Client{ 215 | &warrant.ApiClient{ 216 | HttpClient: warrant.HttpClient, 217 | Config: config, 218 | }, 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /session.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ( 4 | SelfServiceStrategyFGAC = "fgac" 5 | SelfServiceStrategyRBAC = "rbac" 6 | ) 7 | 8 | type Session struct { 9 | UserId string `json:"userId"` 10 | TenantId string `json:"tenantId"` 11 | TTL int64 `json:"ttl"` 12 | } 13 | 14 | type AuthorizationSessionParams struct { 15 | UserId string `json:"userId,omitempty"` 16 | TenantId string `json:"tenantId,omitempty"` 17 | TTL int64 `json:"ttl,omitempty"` 18 | Context PolicyContext `json:"context,omitempty"` 19 | } 20 | 21 | type SelfServiceSessionParams struct { 22 | UserId string `json:"userId"` 23 | TenantId string `json:"tenantId"` 24 | TTL int64 `json:"ttl,omitempty"` 25 | Context PolicyContext `json:"context,omitempty"` 26 | SelfServiceStrategy string `json:"selfServiceStrategy"` 27 | ObjectType string `json:"objectType"` 28 | ObjectId string `json:"objectId"` 29 | RedirectUrl string `json:"redirectUrl"` 30 | } 31 | -------------------------------------------------------------------------------- /session/client.go: -------------------------------------------------------------------------------- 1 | package session 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | 8 | "github.com/warrant-dev/warrant-go/v6" 9 | ) 10 | 11 | type Client struct { 12 | apiClient *warrant.ApiClient 13 | } 14 | 15 | func NewClient(config warrant.ClientConfig) Client { 16 | return Client{ 17 | apiClient: warrant.NewApiClient(config), 18 | } 19 | } 20 | 21 | func (c Client) CreateAuthorizationSession(params *warrant.AuthorizationSessionParams) (string, error) { 22 | if params == nil { 23 | params = &warrant.AuthorizationSessionParams{} 24 | } 25 | sessionParams := map[string]interface{}{ 26 | "type": "sess", 27 | "userId": params.UserId, 28 | "tenantId": params.TenantId, 29 | "ttl": params.TTL, 30 | "context": params.Context, 31 | } 32 | resp, err := c.apiClient.MakeRequest("POST", "/v2/sessions", sessionParams, &warrant.RequestOptions{}) 33 | if err != nil { 34 | return "", err 35 | } 36 | body, err := io.ReadAll(resp.Body) 37 | if err != nil { 38 | return "", warrant.WrapError("Error reading response", err) 39 | } 40 | defer resp.Body.Close() 41 | var response map[string]string 42 | err = json.Unmarshal([]byte(body), &response) 43 | if err != nil { 44 | return "", warrant.WrapError("Invalid response from server", err) 45 | } 46 | return response["token"], nil 47 | } 48 | 49 | func CreateAuthorizationSession(params *warrant.AuthorizationSessionParams) (string, error) { 50 | return getClient().CreateAuthorizationSession(params) 51 | } 52 | 53 | func (c Client) CreateSelfServiceSession(params *warrant.SelfServiceSessionParams) (string, error) { 54 | if params == nil { 55 | params = &warrant.SelfServiceSessionParams{} 56 | } 57 | sessionParams := map[string]interface{}{ 58 | "type": "ssdash", 59 | "userId": params.UserId, 60 | "tenantId": params.TenantId, 61 | "selfServiceStrategy": params.SelfServiceStrategy, 62 | "ttl": params.TTL, 63 | } 64 | if params.ObjectType != "" { 65 | sessionParams["objectType"] = params.ObjectType 66 | } 67 | if params.ObjectId != "" { 68 | sessionParams["objectId"] = params.ObjectId 69 | } 70 | 71 | resp, err := c.apiClient.MakeRequest("POST", "/v2/sessions", sessionParams, &warrant.RequestOptions{}) 72 | if err != nil { 73 | return "", err 74 | } 75 | body, err := io.ReadAll(resp.Body) 76 | if err != nil { 77 | return "", warrant.WrapError("Error reading response", err) 78 | } 79 | defer resp.Body.Close() 80 | var response map[string]string 81 | err = json.Unmarshal([]byte(body), &response) 82 | if err != nil { 83 | return "", warrant.WrapError("Invalid response from server", err) 84 | } 85 | return fmt.Sprintf("%s/%s?redirectUrl=%s", warrant.SelfServiceDashEndpoint, response["token"], params.RedirectUrl), nil 86 | } 87 | 88 | func CreateSelfServiceSession(params *warrant.SelfServiceSessionParams) (string, error) { 89 | return getClient().CreateSelfServiceSession(params) 90 | } 91 | 92 | func getClient() Client { 93 | config := warrant.ClientConfig{ 94 | ApiKey: warrant.ApiKey, 95 | ApiEndpoint: warrant.ApiEndpoint, 96 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 97 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 98 | HttpClient: warrant.HttpClient, 99 | } 100 | 101 | return Client{ 102 | &warrant.ApiClient{ 103 | HttpClient: warrant.HttpClient, 104 | Config: config, 105 | }, 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /tenant.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ObjectTypeTenant = "tenant" 4 | 5 | type Tenant struct { 6 | TenantId string `json:"tenantId"` 7 | Meta map[string]interface{} `json:"meta,omitempty"` 8 | } 9 | 10 | func (tenant Tenant) GetObjectType() string { 11 | return "tenant" 12 | } 13 | 14 | func (tenant Tenant) GetObjectId() string { 15 | return tenant.TenantId 16 | } 17 | 18 | type ListTenantParams struct { 19 | ListParams 20 | } 21 | 22 | type TenantParams struct { 23 | RequestOptions 24 | TenantId string `json:"tenantId,omitempty"` 25 | Meta map[string]interface{} `json:"meta,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /tenant/client.go: -------------------------------------------------------------------------------- 1 | package tenant 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/warrant-dev/warrant-go/v6" 7 | "github.com/warrant-dev/warrant-go/v6/object" 8 | ) 9 | 10 | type Client struct { 11 | apiClient *warrant.ApiClient 12 | } 13 | 14 | func NewClient(config warrant.ClientConfig) Client { 15 | return Client{ 16 | apiClient: warrant.NewApiClient(config), 17 | } 18 | } 19 | 20 | func (c Client) Create(params *warrant.TenantParams) (*warrant.Tenant, error) { 21 | if params == nil { 22 | params = &warrant.TenantParams{} 23 | } 24 | objectParams := warrant.ObjectParams{ 25 | ObjectType: warrant.ObjectTypeTenant, 26 | RequestOptions: params.RequestOptions, 27 | } 28 | if params.TenantId != "" { 29 | objectParams.ObjectId = params.TenantId 30 | } 31 | if params.Meta != nil { 32 | objectParams.Meta = params.Meta 33 | } 34 | object, err := object.Create(&objectParams) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &warrant.Tenant{ 39 | TenantId: object.ObjectId, 40 | Meta: object.Meta, 41 | }, nil 42 | } 43 | 44 | func Create(params *warrant.TenantParams) (*warrant.Tenant, error) { 45 | return getClient().Create(params) 46 | } 47 | 48 | func (c Client) BatchCreate(params []warrant.TenantParams) ([]warrant.Tenant, error) { 49 | objectsToCreate := make([]warrant.ObjectParams, 0) 50 | for _, tenantParam := range params { 51 | objectsToCreate = append(objectsToCreate, warrant.ObjectParams{ 52 | RequestOptions: tenantParam.RequestOptions, 53 | ObjectType: warrant.ObjectTypeTenant, 54 | ObjectId: tenantParam.TenantId, 55 | Meta: tenantParam.Meta, 56 | }) 57 | } 58 | 59 | createdObjects, err := object.BatchCreate(objectsToCreate) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | tenants := make([]warrant.Tenant, 0) 65 | for _, createdObject := range createdObjects { 66 | tenants = append(tenants, warrant.Tenant{ 67 | TenantId: createdObject.ObjectId, 68 | Meta: createdObject.Meta, 69 | }) 70 | } 71 | 72 | return tenants, nil 73 | } 74 | 75 | func BatchCreate(params []warrant.TenantParams) ([]warrant.Tenant, error) { 76 | return getClient().BatchCreate(params) 77 | } 78 | 79 | func (c Client) Get(tenantId string, params *warrant.TenantParams) (*warrant.Tenant, error) { 80 | if params == nil { 81 | params = &warrant.TenantParams{} 82 | } 83 | objectParams := warrant.ObjectParams{ 84 | ObjectType: warrant.ObjectTypeTenant, 85 | ObjectId: tenantId, 86 | RequestOptions: params.RequestOptions, 87 | Meta: params.Meta, 88 | } 89 | object, err := object.Get(warrant.ObjectTypeTenant, tenantId, &objectParams) 90 | if err != nil { 91 | return nil, err 92 | } 93 | return &warrant.Tenant{ 94 | TenantId: object.ObjectId, 95 | Meta: object.Meta, 96 | }, nil 97 | } 98 | 99 | func Get(tenantId string, params *warrant.TenantParams) (*warrant.Tenant, error) { 100 | return getClient().Get(tenantId, params) 101 | } 102 | 103 | func (c Client) Update(tenantId string, params *warrant.TenantParams) (*warrant.Tenant, error) { 104 | if params == nil { 105 | params = &warrant.TenantParams{} 106 | } 107 | objectParams := warrant.ObjectParams{ 108 | ObjectType: warrant.ObjectTypeTenant, 109 | ObjectId: tenantId, 110 | RequestOptions: params.RequestOptions, 111 | Meta: params.Meta, 112 | } 113 | object, err := object.Update(warrant.ObjectTypeTenant, tenantId, &objectParams) 114 | if err != nil { 115 | return nil, err 116 | } 117 | return &warrant.Tenant{ 118 | TenantId: object.ObjectId, 119 | Meta: object.Meta, 120 | }, nil 121 | } 122 | 123 | func Update(tenantId string, params *warrant.TenantParams) (*warrant.Tenant, error) { 124 | return getClient().Update(tenantId, params) 125 | } 126 | 127 | func (c Client) Delete(tenantId string) (string, error) { 128 | return object.Delete(warrant.ObjectTypeTenant, tenantId) 129 | } 130 | 131 | func Delete(tenantId string) (string, error) { 132 | return getClient().Delete(tenantId) 133 | } 134 | 135 | func (c Client) BatchDelete(params []warrant.TenantParams) (string, error) { 136 | objectsToDelete := make([]warrant.ObjectParams, 0) 137 | for _, tenantParam := range params { 138 | objectsToDelete = append(objectsToDelete, warrant.ObjectParams{ 139 | RequestOptions: tenantParam.RequestOptions, 140 | ObjectType: warrant.ObjectTypeTenant, 141 | ObjectId: tenantParam.TenantId, 142 | Meta: tenantParam.Meta, 143 | }) 144 | } 145 | 146 | warrantToken, err := object.BatchDelete(objectsToDelete) 147 | if err != nil { 148 | return "", err 149 | } 150 | 151 | return warrantToken, nil 152 | } 153 | 154 | func BatchDelete(params []warrant.TenantParams) (string, error) { 155 | return getClient().BatchDelete(params) 156 | } 157 | 158 | func (c Client) ListTenants(listParams *warrant.ListTenantParams) (warrant.ListResponse[warrant.Tenant], error) { 159 | if listParams == nil { 160 | listParams = &warrant.ListTenantParams{} 161 | } 162 | var tenantsListResponse warrant.ListResponse[warrant.Tenant] 163 | 164 | objectsListResponse, err := object.ListObjects(&warrant.ListObjectParams{ 165 | ListParams: listParams.ListParams, 166 | ObjectType: warrant.ObjectTypeTenant, 167 | }) 168 | if err != nil { 169 | return tenantsListResponse, err 170 | } 171 | 172 | tenants := make([]warrant.Tenant, 0) 173 | for _, object := range objectsListResponse.Results { 174 | tenants = append(tenants, warrant.Tenant{ 175 | TenantId: object.ObjectId, 176 | Meta: object.Meta, 177 | }) 178 | } 179 | 180 | tenantsListResponse = warrant.ListResponse[warrant.Tenant]{ 181 | Results: tenants, 182 | PrevCursor: objectsListResponse.PrevCursor, 183 | NextCursor: objectsListResponse.NextCursor, 184 | } 185 | 186 | return tenantsListResponse, nil 187 | } 188 | 189 | func ListTenants(listParams *warrant.ListTenantParams) (warrant.ListResponse[warrant.Tenant], error) { 190 | return getClient().ListTenants(listParams) 191 | } 192 | 193 | func (c Client) ListTenantsForUser(userId string, listParams *warrant.ListTenantParams) (warrant.ListResponse[warrant.Tenant], error) { 194 | if listParams == nil { 195 | listParams = &warrant.ListTenantParams{} 196 | } 197 | var tenantsListResponse warrant.ListResponse[warrant.Tenant] 198 | 199 | queryResponse, err := warrant.Query(fmt.Sprintf("select tenant where user:%s is *", userId), &warrant.QueryParams{ 200 | ListParams: listParams.ListParams, 201 | }) 202 | if err != nil { 203 | return tenantsListResponse, err 204 | } 205 | 206 | tenants := make([]warrant.Tenant, 0) 207 | for _, queryResult := range queryResponse.Results { 208 | tenants = append(tenants, warrant.Tenant{ 209 | TenantId: queryResult.ObjectId, 210 | Meta: queryResult.Meta, 211 | }) 212 | } 213 | 214 | tenantsListResponse = warrant.ListResponse[warrant.Tenant]{ 215 | Results: tenants, 216 | PrevCursor: queryResponse.PrevCursor, 217 | NextCursor: queryResponse.NextCursor, 218 | } 219 | 220 | return tenantsListResponse, nil 221 | } 222 | 223 | func ListTenantsForUser(userId string, listParams *warrant.ListTenantParams) (warrant.ListResponse[warrant.Tenant], error) { 224 | return getClient().ListTenantsForUser(userId, listParams) 225 | } 226 | 227 | func getClient() Client { 228 | config := warrant.ClientConfig{ 229 | ApiKey: warrant.ApiKey, 230 | ApiEndpoint: warrant.ApiEndpoint, 231 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 232 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 233 | HttpClient: warrant.HttpClient, 234 | } 235 | 236 | return Client{ 237 | &warrant.ApiClient{ 238 | HttpClient: warrant.HttpClient, 239 | Config: config, 240 | }, 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /user.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | const ObjectTypeUser = "user" 4 | 5 | type User struct { 6 | UserId string `json:"userId"` 7 | Meta map[string]interface{} `json:"meta,omitempty"` 8 | } 9 | 10 | func (user User) GetObjectType() string { 11 | return "user" 12 | } 13 | 14 | func (user User) GetObjectId() string { 15 | return user.UserId 16 | } 17 | 18 | type ListUserParams struct { 19 | ListParams 20 | } 21 | 22 | type UserParams struct { 23 | RequestOptions 24 | UserId string `json:"userId,omitempty"` 25 | Meta map[string]interface{} `json:"meta,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /user/client.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/warrant-dev/warrant-go/v6" 7 | "github.com/warrant-dev/warrant-go/v6/object" 8 | ) 9 | 10 | type Client struct { 11 | apiClient *warrant.ApiClient 12 | } 13 | 14 | func NewClient(config warrant.ClientConfig) Client { 15 | return Client{ 16 | apiClient: warrant.NewApiClient(config), 17 | } 18 | } 19 | 20 | func (c Client) Create(params *warrant.UserParams) (*warrant.User, error) { 21 | if params == nil { 22 | params = &warrant.UserParams{} 23 | } 24 | objectParams := warrant.ObjectParams{ 25 | ObjectType: warrant.ObjectTypeUser, 26 | RequestOptions: params.RequestOptions, 27 | } 28 | if params.UserId != "" { 29 | objectParams.ObjectId = params.UserId 30 | } 31 | if params.Meta != nil { 32 | objectParams.Meta = params.Meta 33 | } 34 | object, err := object.Create(&objectParams) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &warrant.User{ 39 | UserId: object.ObjectId, 40 | Meta: object.Meta, 41 | }, nil 42 | } 43 | 44 | func Create(params *warrant.UserParams) (*warrant.User, error) { 45 | return getClient().Create(params) 46 | } 47 | 48 | func (c Client) BatchCreate(params []warrant.UserParams) ([]warrant.User, error) { 49 | objectsToCreate := make([]warrant.ObjectParams, 0) 50 | for _, userParam := range params { 51 | objectsToCreate = append(objectsToCreate, warrant.ObjectParams{ 52 | RequestOptions: userParam.RequestOptions, 53 | ObjectType: warrant.ObjectTypeUser, 54 | ObjectId: userParam.UserId, 55 | Meta: userParam.Meta, 56 | }) 57 | } 58 | 59 | createdObjects, err := object.BatchCreate(objectsToCreate) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | users := make([]warrant.User, 0) 65 | for _, createdObject := range createdObjects { 66 | users = append(users, warrant.User{ 67 | UserId: createdObject.ObjectId, 68 | Meta: createdObject.Meta, 69 | }) 70 | } 71 | 72 | return users, nil 73 | } 74 | 75 | func BatchCreate(params []warrant.UserParams) ([]warrant.User, error) { 76 | return getClient().BatchCreate(params) 77 | } 78 | 79 | func (c Client) Get(userId string, params *warrant.UserParams) (*warrant.User, error) { 80 | if params == nil { 81 | params = &warrant.UserParams{} 82 | } 83 | objectParams := warrant.ObjectParams{ 84 | ObjectType: warrant.ObjectTypeUser, 85 | ObjectId: userId, 86 | RequestOptions: params.RequestOptions, 87 | Meta: params.Meta, 88 | } 89 | object, err := object.Get(warrant.ObjectTypeUser, userId, &objectParams) 90 | if err != nil { 91 | return nil, err 92 | } 93 | return &warrant.User{ 94 | UserId: object.ObjectId, 95 | Meta: object.Meta, 96 | }, nil 97 | } 98 | 99 | func Get(userId string, params *warrant.UserParams) (*warrant.User, error) { 100 | return getClient().Get(userId, params) 101 | } 102 | 103 | func (c Client) Update(userId string, params *warrant.UserParams) (*warrant.User, error) { 104 | if params == nil { 105 | params = &warrant.UserParams{} 106 | } 107 | objectParams := warrant.ObjectParams{ 108 | ObjectType: warrant.ObjectTypeUser, 109 | ObjectId: userId, 110 | RequestOptions: params.RequestOptions, 111 | Meta: params.Meta, 112 | } 113 | object, err := object.Update(warrant.ObjectTypeUser, userId, &objectParams) 114 | if err != nil { 115 | return nil, err 116 | } 117 | return &warrant.User{ 118 | UserId: object.ObjectId, 119 | Meta: object.Meta, 120 | }, nil 121 | } 122 | 123 | func Update(userId string, params *warrant.UserParams) (*warrant.User, error) { 124 | return getClient().Update(userId, params) 125 | } 126 | 127 | func (c Client) Delete(userId string) (string, error) { 128 | return object.Delete(warrant.ObjectTypeUser, userId) 129 | } 130 | 131 | func Delete(userId string) (string, error) { 132 | return getClient().Delete(userId) 133 | } 134 | 135 | func (c Client) BatchDelete(params []warrant.UserParams) (string, error) { 136 | objectsToDelete := make([]warrant.ObjectParams, 0) 137 | for _, userParam := range params { 138 | objectsToDelete = append(objectsToDelete, warrant.ObjectParams{ 139 | RequestOptions: userParam.RequestOptions, 140 | ObjectType: warrant.ObjectTypeUser, 141 | ObjectId: userParam.UserId, 142 | Meta: userParam.Meta, 143 | }) 144 | } 145 | 146 | warrantToken, err := object.BatchDelete(objectsToDelete) 147 | if err != nil { 148 | return "", err 149 | } 150 | 151 | return warrantToken, nil 152 | } 153 | 154 | func BatchDelete(params []warrant.UserParams) (string, error) { 155 | return getClient().BatchDelete(params) 156 | } 157 | 158 | func (c Client) ListUsers(listParams *warrant.ListUserParams) (warrant.ListResponse[warrant.User], error) { 159 | if listParams == nil { 160 | listParams = &warrant.ListUserParams{} 161 | } 162 | var usersListResponse warrant.ListResponse[warrant.User] 163 | 164 | objectsListResponse, err := object.ListObjects(&warrant.ListObjectParams{ 165 | ListParams: listParams.ListParams, 166 | ObjectType: warrant.ObjectTypeUser, 167 | }) 168 | if err != nil { 169 | return usersListResponse, err 170 | } 171 | 172 | users := make([]warrant.User, 0) 173 | for _, object := range objectsListResponse.Results { 174 | users = append(users, warrant.User{ 175 | UserId: object.ObjectId, 176 | Meta: object.Meta, 177 | }) 178 | } 179 | 180 | usersListResponse = warrant.ListResponse[warrant.User]{ 181 | Results: users, 182 | PrevCursor: objectsListResponse.PrevCursor, 183 | NextCursor: objectsListResponse.NextCursor, 184 | } 185 | 186 | return usersListResponse, nil 187 | } 188 | 189 | func ListUsers(listParams *warrant.ListUserParams) (warrant.ListResponse[warrant.User], error) { 190 | return getClient().ListUsers(listParams) 191 | } 192 | 193 | func (c Client) ListUsersForTenant(tenantId string, listParams *warrant.ListUserParams) (warrant.ListResponse[warrant.User], error) { 194 | if listParams == nil { 195 | listParams = &warrant.ListUserParams{} 196 | } 197 | var usersListResponse warrant.ListResponse[warrant.User] 198 | 199 | queryResponse, err := warrant.Query(fmt.Sprintf("select * of type user for tenant:%s", tenantId), &warrant.QueryParams{ 200 | ListParams: listParams.ListParams, 201 | }) 202 | if err != nil { 203 | return usersListResponse, err 204 | } 205 | 206 | users := make([]warrant.User, 0) 207 | for _, queryResult := range queryResponse.Results { 208 | users = append(users, warrant.User{ 209 | UserId: queryResult.ObjectId, 210 | Meta: queryResult.Meta, 211 | }) 212 | } 213 | 214 | usersListResponse = warrant.ListResponse[warrant.User]{ 215 | Results: users, 216 | PrevCursor: queryResponse.PrevCursor, 217 | NextCursor: queryResponse.NextCursor, 218 | } 219 | 220 | return usersListResponse, nil 221 | } 222 | 223 | func ListUsersForTenant(tenantId string, listParams *warrant.ListUserParams) (warrant.ListResponse[warrant.User], error) { 224 | return getClient().ListUsersForTenant(tenantId, listParams) 225 | } 226 | 227 | func (c Client) AssignUserToTenant(userId string, tenantId string, role string) (*warrant.Warrant, error) { 228 | return warrant.Create(&warrant.WarrantParams{ 229 | ObjectType: warrant.ObjectTypeTenant, 230 | ObjectId: tenantId, 231 | Relation: role, 232 | Subject: warrant.Subject{ 233 | ObjectType: warrant.ObjectTypeUser, 234 | ObjectId: userId, 235 | }, 236 | }) 237 | } 238 | 239 | func AssignUserToTenant(userId string, tenantId string, role string) (*warrant.Warrant, error) { 240 | return getClient().AssignUserToTenant(userId, tenantId, role) 241 | } 242 | 243 | func (c Client) RemoveUserFromTenant(userId string, tenantId string, role string) (string, error) { 244 | return warrant.Delete(&warrant.WarrantParams{ 245 | ObjectType: warrant.ObjectTypeTenant, 246 | ObjectId: tenantId, 247 | Relation: role, 248 | Subject: warrant.Subject{ 249 | ObjectType: warrant.ObjectTypeUser, 250 | ObjectId: userId, 251 | }, 252 | }) 253 | } 254 | 255 | func RemoveUserFromTenant(userId string, tenantId string, role string) (string, error) { 256 | return getClient().RemoveUserFromTenant(userId, tenantId, role) 257 | } 258 | 259 | func getClient() Client { 260 | config := warrant.ClientConfig{ 261 | ApiKey: warrant.ApiKey, 262 | ApiEndpoint: warrant.ApiEndpoint, 263 | AuthorizeEndpoint: warrant.AuthorizeEndpoint, 264 | SelfServiceDashEndpoint: warrant.SelfServiceDashEndpoint, 265 | HttpClient: warrant.HttpClient, 266 | } 267 | 268 | return Client{ 269 | &warrant.ApiClient{ 270 | HttpClient: warrant.HttpClient, 271 | Config: config, 272 | }, 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /warrant.go: -------------------------------------------------------------------------------- 1 | package warrant 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type Warrant struct { 8 | ObjectType string `json:"objectType"` 9 | ObjectId string `json:"objectId"` 10 | Relation string `json:"relation"` 11 | Subject Subject `json:"subject"` 12 | Policy string `json:"policy,omitempty"` 13 | IsImplicit bool `json:"isImplicit,omitempty"` 14 | WarrantToken string `json:"warrantToken,omitempty"` 15 | } 16 | 17 | type PolicyContext map[string]interface{} 18 | 19 | type Subject struct { 20 | ObjectType string `json:"objectType"` 21 | ObjectId string `json:"objectId"` 22 | Relation string `json:"relation,omitempty"` 23 | } 24 | 25 | func (subject Subject) GetObjectType() string { 26 | return subject.ObjectType 27 | } 28 | 29 | func (subject Subject) GetObjectId() string { 30 | return subject.ObjectId 31 | } 32 | 33 | func (subject Subject) GetRelation() string { 34 | return subject.Relation 35 | } 36 | 37 | type WarrantParams struct { 38 | ObjectType string `json:"objectType"` 39 | ObjectId string `json:"objectId"` 40 | Relation string `json:"relation"` 41 | Subject Subject `json:"subject"` 42 | Policy string `json:"policy,omitempty"` 43 | } 44 | 45 | type ListWarrantParams struct { 46 | ListParams 47 | ObjectType string `json:"objectType,omitempty" url:"objectType,omitempty"` 48 | ObjectId string `json:"objectId,omitempty" url:"objectId,omitempty"` 49 | Relation string `json:"relation,omitempty" url:"relation,omitempty"` 50 | SubjectType string `json:"subjectType,omitempty" url:"subjectType,omitempty"` 51 | SubjectId string `json:"subjectId,omitempty" url:"subjectId,omitempty"` 52 | SubjectRelation string `json:"subjectRelation,omitempty" url:"subjectRelation,omitempty"` 53 | } 54 | 55 | type Object struct { 56 | ObjectType string `json:"objectType"` 57 | ObjectId string `json:"objectId"` 58 | Meta map[string]interface{} `json:"meta"` 59 | } 60 | 61 | func (object Object) GetObjectType() string { 62 | return object.ObjectType 63 | } 64 | 65 | func (object Object) GetObjectId() string { 66 | return object.ObjectId 67 | } 68 | 69 | type ObjectParams struct { 70 | RequestOptions 71 | ObjectType string `json:"objectType"` 72 | ObjectId string `json:"objectId,omitempty"` 73 | Meta map[string]interface{} `json:"meta,omitempty"` 74 | } 75 | 76 | type ListObjectParams struct { 77 | ListParams 78 | ObjectType string `json:"objectType,omitempty" url:"objectType,omitempty"` 79 | Query string `json:"q,omitempty" url:"q,omitempty"` 80 | } 81 | 82 | type WarrantObject interface { 83 | GetObjectType() string 84 | GetObjectId() string 85 | } 86 | 87 | type WarrantCheck struct { 88 | Object WarrantObject `json:"object"` 89 | Relation string `json:"relation"` 90 | Subject WarrantObject `json:"subject"` 91 | Context PolicyContext `json:"context,omitempty"` 92 | } 93 | 94 | func (warrantCheck WarrantCheck) MarshalJSON() ([]byte, error) { 95 | var m map[string]interface{} 96 | subject, ok := warrantCheck.Subject.(*Subject) 97 | if ok { 98 | m = map[string]interface{}{ 99 | "objectType": warrantCheck.Object.GetObjectType(), 100 | "objectId": warrantCheck.Object.GetObjectId(), 101 | "relation": warrantCheck.Relation, 102 | "subject": map[string]interface{}{ 103 | "objectType": subject.GetObjectType(), 104 | "objectId": subject.GetObjectId(), 105 | "relation": subject.GetRelation(), 106 | }, 107 | "context": warrantCheck.Context, 108 | } 109 | } else { 110 | m = map[string]interface{}{ 111 | "objectType": warrantCheck.Object.GetObjectType(), 112 | "objectId": warrantCheck.Object.GetObjectId(), 113 | "relation": warrantCheck.Relation, 114 | "subject": map[string]interface{}{ 115 | "objectType": warrantCheck.Subject.GetObjectType(), 116 | "objectId": warrantCheck.Subject.GetObjectId(), 117 | }, 118 | "context": warrantCheck.Context, 119 | } 120 | } 121 | 122 | return json.Marshal(m) 123 | } 124 | 125 | type WarrantCheckParams struct { 126 | RequestOptions 127 | WarrantCheck WarrantCheck `json:"warrantCheck"` 128 | Debug bool `json:"debug,omitempty"` 129 | } 130 | 131 | type WarrantCheckManyParams struct { 132 | RequestOptions 133 | Op string `json:"op"` 134 | Warrants []WarrantCheck `json:"warrants"` 135 | Debug bool `json:"debug,omitempty"` 136 | } 137 | 138 | type WarrantCheckResult struct { 139 | Code int64 `json:"code"` 140 | Result string `json:"result"` 141 | } 142 | 143 | type PermissionCheckParams struct { 144 | RequestOptions 145 | PermissionId string `json:"permissionId"` 146 | UserId string `json:"userId"` 147 | Context PolicyContext `json:"context,omitempty"` 148 | Debug bool `json:"debug,omitempty"` 149 | } 150 | 151 | type RoleCheckParams struct { 152 | RequestOptions 153 | RoleId string `json:"roleId"` 154 | UserId string `json:"userId"` 155 | Context PolicyContext `json:"context,omitempty"` 156 | Debug bool `json:"debug,omitempty"` 157 | } 158 | 159 | type FeatureCheckParams struct { 160 | RequestOptions 161 | FeatureId string `json:"featureId"` 162 | Subject Subject `json:"subject"` 163 | Context PolicyContext `json:"context,omitempty"` 164 | Debug bool `json:"debug,omitempty"` 165 | } 166 | 167 | type AccessCheckRequest struct { 168 | RequestOptions 169 | Op string `json:"op"` 170 | Warrants []WarrantCheck `json:"warrants"` 171 | Debug bool `json:"debug,omitempty"` 172 | } 173 | --------------------------------------------------------------------------------