From cac076934e6c97327ca766cc016e2906660deaff Mon Sep 17 00:00:00 2001 From: kompotkot Date: Wed, 17 Apr 2024 11:16:08 +0000 Subject: [PATCH 1/2] Fetch holders additional data name, etc --- bugout.go | 135 +++++++++++++++++++++++++++++++++++++----------------- server.go | 62 ++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 42 deletions(-) diff --git a/bugout.go b/bugout.go index 072e719..bf6604a 100644 --- a/bugout.go +++ b/bugout.go @@ -172,100 +172,153 @@ func ProcessDropperClaims(client *bugout.BugoutClient, bugoutToken, journalID, c return processedErr } +type RequestResourceHolder struct { + HolderId string `json:"holder_id"` + HolderType string `json:"holder_type"` + Permissions []string `json:"permissions"` +} + +type ResourceHolder struct { + Id string `json:"id"` + HolderType string `json:"holder_type"` + Permissions []string `json:"permissions"` +} + +type ResourceHolderUser struct { + Id string `json:"id"` + Username string `json:"username"` + ApplicationId string `json:"application_id"` + HolderType string `json:"holder_type"` + Permissions []string `json:"permissions"` +} + +type ResourceHolderGroup struct { + Id string `json:"id"` + Name string `json:"name"` + Autogenerated bool `json:"autogenerated"` + HolderType string `json:"holder_type"` + Permissions []string `json:"permissions"` +} + +type ResourceHolders struct { + ResourceId string `json:"resource_id"` + Holders []ResourceHolder `json:"holders"` +} + +func (c *BugoutAPIClient) CheckAccessToResource(token, resourceId string) (ResourceHolders, int, error) { + var resourceHolders ResourceHolders + + var requestBodyBytes []byte + request, requestErr := http.NewRequest("GET", fmt.Sprintf("%s/resources/%s/holders", c.BroodBaseURL, resourceId), bytes.NewBuffer(requestBodyBytes)) + if requestErr != nil { + return resourceHolders, 500, requestErr + } + + request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + request.Header.Add("Accept", "application/json") + request.Header.Add("Content-Type", "application/json") + + response, responseErr := c.HTTPClient.Do(request) + if responseErr != nil { + return resourceHolders, 500, responseErr + } + defer response.Body.Close() + + responseBody, responseBodyErr := io.ReadAll(response.Body) + if responseBodyErr != nil { + return resourceHolders, response.StatusCode, fmt.Errorf("could not read response body: %s", responseBodyErr.Error()) + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return resourceHolders, response.StatusCode, fmt.Errorf("unexpected status code: %d -- could not read response body: %s", response.StatusCode, response.Status) + } + + unmarshalErr := json.Unmarshal(responseBody, &resourceHolders) + if unmarshalErr != nil { + return resourceHolders, response.StatusCode, fmt.Errorf("could not parse response body: %s", unmarshalErr.Error()) + } + + return resourceHolders, response.StatusCode, nil +} + type User struct { Id string `json:"user_id"` Username string `json:"username"` ApplicationId string `json:"application_id"` } -func (c *BugoutAPIClient) GetUser(accessToken string) (User, error) { +func (c *BugoutAPIClient) FindUser(token, userId string) (User, int, error) { var user User var requestBodyBytes []byte - request, requestErr := http.NewRequest("GET", fmt.Sprintf("%s/user", c.BroodBaseURL), bytes.NewBuffer(requestBodyBytes)) + request, requestErr := http.NewRequest("GET", fmt.Sprintf("%s/user/find2?user_id=%s", c.BroodBaseURL, userId), bytes.NewBuffer(requestBodyBytes)) if requestErr != nil { - return user, requestErr + return user, 500, requestErr } - request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken)) + request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) request.Header.Add("Accept", "application/json") request.Header.Add("Content-Type", "application/json") response, responseErr := c.HTTPClient.Do(request) if responseErr != nil { - return user, responseErr + return user, 500, requestErr } defer response.Body.Close() responseBody, responseBodyErr := io.ReadAll(response.Body) - - if response.StatusCode < 200 || response.StatusCode >= 300 { - if responseBodyErr != nil { - return user, fmt.Errorf("unexpected status code: %d -- could not read response body: %s", response.StatusCode, responseBodyErr.Error()) - } + if responseBodyErr != nil { + return user, response.StatusCode, fmt.Errorf("could not read response body: %s", responseBodyErr.Error()) } - if responseBodyErr != nil { - return user, fmt.Errorf("could not read response body: %s", responseBodyErr.Error()) + if response.StatusCode < 200 || response.StatusCode >= 300 { + return user, response.StatusCode, fmt.Errorf("unexpected status code: %d -- could not read response body: %s", response.StatusCode, response.Status) } unmarshalErr := json.Unmarshal(responseBody, &user) if unmarshalErr != nil { - return user, fmt.Errorf("could not parse response body: %s", unmarshalErr.Error()) + return user, response.StatusCode, fmt.Errorf("could not parse response body: %s", unmarshalErr.Error()) } - return user, nil -} - -type RequestResourceHolder struct { - HolderId string `json:"holder_id"` - HolderType string `json:"holder_type"` - Permissions []string `json:"permissions"` -} - -type ResourceHolder struct { - Id string `json:"id"` - HolderType string `json:"holder_type"` - Permissions []string `json:"permissions"` + return user, response.StatusCode, nil } -type ResourceHolders struct { - ResourceId string `json:"resource_id"` - Holders []ResourceHolder `json:"holders"` +type Group struct { + Id string `json:"user_id"` + Name string `json:"name"` + Autogenerated bool `json:"autogenerated"` } -func (c *BugoutAPIClient) CheckAccessToResource(token, resourceId string) (ResourceHolders, int, error) { - var resourceHolders ResourceHolders - +func (c *BugoutAPIClient) FindGroup(token, groupId string) (Group, int, error) { + var group Group var requestBodyBytes []byte - request, requestErr := http.NewRequest("GET", fmt.Sprintf("%s/resources/%s/holders", c.BroodBaseURL, resourceId), bytes.NewBuffer(requestBodyBytes)) + request, requestErr := http.NewRequest("GET", fmt.Sprintf("%s/group/find?group_id=%s", c.BroodBaseURL, groupId), bytes.NewBuffer(requestBodyBytes)) if requestErr != nil { - return resourceHolders, 500, requestErr + return group, 500, requestErr } - request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) request.Header.Add("Accept", "application/json") request.Header.Add("Content-Type", "application/json") response, responseErr := c.HTTPClient.Do(request) if responseErr != nil { - return resourceHolders, 500, responseErr + return group, 500, requestErr } defer response.Body.Close() responseBody, responseBodyErr := io.ReadAll(response.Body) if responseBodyErr != nil { - return resourceHolders, response.StatusCode, fmt.Errorf("could not read response body: %s", responseBodyErr.Error()) + return group, response.StatusCode, fmt.Errorf("could not read response body: %s", responseBodyErr.Error()) } if response.StatusCode < 200 || response.StatusCode >= 300 { - return resourceHolders, response.StatusCode, fmt.Errorf("unexpected status code: %d -- could not read response body: %s", response.StatusCode, response.Status) + return group, response.StatusCode, fmt.Errorf("unexpected status code: %d -- could not read response body: %s", response.StatusCode, response.Status) } - unmarshalErr := json.Unmarshal(responseBody, &resourceHolders) + unmarshalErr := json.Unmarshal(responseBody, &group) if unmarshalErr != nil { - return resourceHolders, response.StatusCode, fmt.Errorf("could not parse response body: %s", unmarshalErr.Error()) + return group, response.StatusCode, fmt.Errorf("could not parse response body: %s", unmarshalErr.Error()) } - return resourceHolders, response.StatusCode, nil + return group, response.StatusCode, nil } func (c *BugoutAPIClient) ModifyAccessToResource(token, resourceId, method string, requestResourceHolder *RequestResourceHolder) (ResourceHolders, int, error) { diff --git a/server.go b/server.go index fa50463..6b0bd3c 100644 --- a/server.go +++ b/server.go @@ -252,8 +252,68 @@ func (server *Server) holdersHandler(w http.ResponseWriter, r *http.Request) { func (server *Server) holdersRoute(w http.ResponseWriter, r *http.Request) { authorizationContext := r.Context().Value("authorizationContext").(AuthorizationContext) accessResourceHolders := authorizationContext.AccessResourceHolders + authorizationToken := authorizationContext.AuthorizationToken + + var holders []interface{} + maxRequests := 4 + holdersLen := len(accessResourceHolders.Holders) + + sem := make(chan struct{}, 3) + var wg sync.WaitGroup + + // Extend holders with names and additional data + for i, h := range accessResourceHolders.Holders { + wg.Add(1) + go func(wg *sync.WaitGroup, sem chan struct{}, h ResourceHolder) { + defer wg.Done() + sem <- struct{}{} + + if h.HolderType == "user" { + user, statusCode, userErr := server.BugoutAPIClient.FindUser(authorizationToken, h.Id) + if userErr != nil { + log.Println(statusCode, userErr) + holders = append(holders, h) + } else { + rhUser := ResourceHolderUser{ + Id: h.Id, + Username: user.Username, + ApplicationId: user.ApplicationId, + HolderType: h.HolderType, + Permissions: h.Permissions, + } + holders = append(holders, rhUser) + } + } else if h.HolderType == "group" { + group, statusCode, groupErr := server.BugoutAPIClient.FindGroup(authorizationToken, h.Id) + if groupErr != nil { + log.Println(statusCode, groupErr) + holders = append(holders, h) + } else { + rhGroup := ResourceHolderGroup{ + Id: h.Id, + Name: group.Name, + Autogenerated: group.Autogenerated, + HolderType: h.HolderType, + Permissions: h.Permissions, + } + holders = append(holders, rhGroup) + } + } else { + log.Printf("Unexpected holder type: %s\n", h.HolderType) + holders = append(holders, h) + } + <-sem + }(&wg, sem, h) + + if (i+1)%maxRequests == 0 && i+1 != holdersLen+1 { + time.Sleep(50 * time.Millisecond) + } + } + wg.Wait() + close(sem) + w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(accessResourceHolders.Holders) + json.NewEncoder(w).Encode(holders) } func (server *Server) modifyHolderAccessRoute(w http.ResponseWriter, r *http.Request, method string) { From 2adb160bf16e8dc66288313d89efba39598d4e42 Mon Sep 17 00:00:00 2001 From: kompotkot Date: Wed, 17 Apr 2024 13:44:52 +0000 Subject: [PATCH 2/2] Bumped version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 89f39bb..c9ef241 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package main -var WAGGLE_VERSION = "0.1.8" +var WAGGLE_VERSION = "0.1.9"