Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch holders additional data name, etc #33

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 94 additions & 41 deletions bugout.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
62 changes: 61 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading