- Notifications
You must be signed in to change notification settings - Fork1k
chore: allow organization name or uuid for audit log searching#13721
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -177,13 +177,48 @@ func TestAuditLogs(t *testing.T) { | ||
// Using the organization selector allows the org admin to fetch audit logs | ||
alogs, err := orgAdmin.AuditLogs(ctx, codersdk.AuditLogsRequest{ | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more.
EDIT: undocumented feature | ||
SearchQuery: fmt.Sprintf("organization:%s", owner.OrganizationID.String()), | ||
Pagination: codersdk.Pagination{ | ||
Limit: 5, | ||
}, | ||
}) | ||
require.NoError(t, err) | ||
require.Len(t, alogs.AuditLogs, 1) | ||
// Also try fetching by organization name | ||
organization, err := orgAdmin.Organization(ctx, owner.OrganizationID) | ||
require.NoError(t, err) | ||
alogs, err = orgAdmin.AuditLogs(ctx, codersdk.AuditLogsRequest{ | ||
SearchQuery: fmt.Sprintf("organization:%s", organization.Name), | ||
Pagination: codersdk.Pagination{ | ||
Limit: 5, | ||
}, | ||
}) | ||
require.NoError(t, err) | ||
require.Len(t, alogs.AuditLogs, 1) | ||
}) | ||
t.Run("Organization404", func(t *testing.T) { | ||
t.Parallel() | ||
logger := slogtest.Make(t, &slogtest.Options{ | ||
IgnoreErrors: true, | ||
}) | ||
ctx := context.Background() | ||
client := coderdtest.New(t, &coderdtest.Options{ | ||
Logger: &logger, | ||
}) | ||
owner := coderdtest.CreateFirstUser(t, client) | ||
orgAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.ScopedRoleOrgAdmin(owner.OrganizationID)) | ||
_, err := orgAdmin.AuditLogs(ctx, codersdk.AuditLogsRequest{ | ||
SearchQuery: fmt.Sprintf("organization:%s", "random-name"), | ||
Pagination: codersdk.Pagination{ | ||
Limit: 5, | ||
}, | ||
}) | ||
require.Error(t, err) | ||
}) | ||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package searchquery | ||
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
"net/url" | ||
@@ -16,7 +17,9 @@ import ( | ||
"github.com/coder/coder/v2/codersdk" | ||
) | ||
// AuditLogs requires the database to fetch an organization by name | ||
// to convert to organization uuid. | ||
func AuditLogs(ctx context.Context, db database.Store, query string) (database.GetAuditLogsOffsetParams, []codersdk.ValidationError) { | ||
// Always lowercase for all searches. | ||
query = strings.ToLower(query) | ||
values, errors := searchTerms(query, func(term string, values url.Values) error { | ||
@@ -30,7 +33,6 @@ func AuditLogs(query string) (database.GetAuditLogsOffsetParams, []codersdk.Vali | ||
const dateLayout = "2006-01-02" | ||
parser := httpapi.NewQueryParamParser() | ||
filter := database.GetAuditLogsOffsetParams{ | ||
ResourceID: parser.UUID(values, uuid.Nil, "resource_id"), | ||
ResourceTarget: parser.String(values, "", "resource_target"), | ||
Username: parser.String(values, "", "username"), | ||
@@ -44,6 +46,28 @@ func AuditLogs(query string) (database.GetAuditLogsOffsetParams, []codersdk.Vali | ||
if !filter.DateTo.IsZero() { | ||
filter.DateTo = filter.DateTo.Add(23*time.Hour + 59*time.Minute + 59*time.Second) | ||
} | ||
// Convert the "organization" parameter to an organization uuid. This can require | ||
// a database lookup. | ||
organizationArg := parser.String(values, "", "organization") | ||
if organizationArg != "" { | ||
organizationID, err := uuid.Parse(organizationArg) | ||
if err == nil { | ||
filter.OrganizationID = organizationID | ||
} else { | ||
// Organization could be a name | ||
organization, err := db.GetOrganizationByName(ctx, organizationArg) | ||
if err != nil { | ||
Comment on lines +57 to +60 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. ah my bad, I fixated on line 33 but missed this check 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Yea, I use the same query param of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Might be worth adding some sort of error if you use Note that this param is not documented or used anywhere yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Only problem is this might break existing queries, idk if any folks would have a reason to use this yet? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more.
Ah, if it's not documented then all bets are off. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Yea, I added it 2 days ago, and intentionally am not documenting any of the multi-org stuff yet:#13663 | ||
parser.Errors = append(parser.Errors, codersdk.ValidationError{ | ||
Field: "organization", | ||
Detail: fmt.Sprintf("Organization %q either does not exist, or you are unauthorized to view it", organizationArg), | ||
}) | ||
} else { | ||
filter.OrganizationID = organization.ID | ||
} | ||
} | ||
} | ||
parser.ErrorExcessParams(values) | ||
return filter, parser.Errors | ||
} | ||