Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/jfreda/support-group-approvals' …
Browse files Browse the repository at this point in the history
…into jeffdaley/google-groups
  • Loading branch information
jeffdaley committed Mar 29, 2024
2 parents 1373d06 + 4374ae2 commit d676511
Showing 1 changed file with 67 additions and 12 deletions.
79 changes: 67 additions & 12 deletions internal/api/v2/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import (
"strings"

"github.com/hashicorp-forge/hermes/internal/server"
admin "google.golang.org/api/admin/directory/v1"
)

const (
// maxGroupResults is the maximum total number of group results to return.
maxGroupResults = 20

// maxPrefixGroupResults is the maximum number of group results to return that
// use the groups prefix, if configured.
maxPrefixGroupResults = 10
)

type GroupsPostRequest struct {
Expand Down Expand Up @@ -55,24 +65,43 @@ func GroupsHandler(srv server.Server) http.Handler {
query := req.Query
query = strings.ReplaceAll(query, " ", "-")

// Apply groups prefix, if applicable.
var (
allGroups []*admin.Group
err error
groups, prefixGroups *admin.Groups
maxNonPrefixGroups = maxGroupResults
)

// Retrieve groups with prefix, if configured.
if srv.Config.GoogleWorkspace.GroupsPrefix != "" {
// Only apply prefix if it looks like the user isn't beginning to type
// it.
if !strings.HasPrefix(srv.Config.GoogleWorkspace.GroupsPrefix, query) {
query = fmt.Sprintf(
"%s%s", srv.Config.GoogleWorkspace.GroupsPrefix, query)
maxNonPrefixGroups = maxGroupResults - maxPrefixGroupResults

prefixQuery := fmt.Sprintf(
"%s%s", srv.Config.GoogleWorkspace.GroupsPrefix, query)
prefixGroups, err = srv.GWService.AdminDirectory.Groups.List().
Domain(srv.Config.GoogleWorkspace.Domain).
MaxResults(maxPrefixGroupResults).
Query(fmt.Sprintf("email:%s*", prefixQuery)).
Do()
if err != nil {
srv.Logger.Error("error searching groups with prefix",
append([]interface{}{
"error", err,
}, logArgs...)...)
http.Error(w, fmt.Sprintf("Error searching groups: %q", err),
http.StatusInternalServerError)
return
}
}

// Retrieve groups.
groups, err := srv.GWService.AdminDirectory.Groups.List().
// Retrieve groups without prefix.
groups, err = srv.GWService.AdminDirectory.Groups.List().
Domain(srv.Config.GoogleWorkspace.Domain).
MaxResults(10).
MaxResults(int64(maxNonPrefixGroups)).
Query(fmt.Sprintf("email:%s*", query)).
Do()
if err != nil {
srv.Logger.Error("error searching groups",
srv.Logger.Error("error searching groups without prefix",
append([]interface{}{
"error", err,
}, logArgs...)...)
Expand All @@ -81,9 +110,12 @@ func GroupsHandler(srv server.Server) http.Handler {
return
}

allGroups = concatGroupSlicesAndRemoveDuplicates(
prefixGroups.Groups, groups.Groups)

// Build response, stripping all attributes except email and name.
resp := make(GroupsPostResponse, len(groups.Groups))
for i, group := range groups.Groups {
resp := make(GroupsPostResponse, len(allGroups))
for i, group := range allGroups {
resp[i] = GroupsPostResponseGroup{
Email: group.Email,
Name: group.Name,
Expand Down Expand Up @@ -111,3 +143,26 @@ func GroupsHandler(srv server.Server) http.Handler {
}
})
}

// concatGroupSlicesAndRemoveDuplicates concatenates two group slices and
// removes any duplicate elements from the result.
func concatGroupSlicesAndRemoveDuplicates(
slice1, slice2 []*admin.Group) []*admin.Group {
uniqueMap := make(map[string]*admin.Group)
result := []*admin.Group{}

// Add elements from both slices to the map.
for _, g := range slice1 {
uniqueMap[g.Email] = g
}
for _, g := range slice2 {
uniqueMap[g.Email] = g
}

// Add all unique elements from the map to the result slice.
for _, v := range uniqueMap {
result = append(result, v)
}

return result
}

0 comments on commit d676511

Please sign in to comment.