Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit736884f

Browse files
committed
feat: add shared_with_group search filter
1 parent01a8eb0 commit736884f

File tree

5 files changed

+133
-5
lines changed

5 files changed

+133
-5
lines changed

‎coderd/database/modelqueries.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
277277
arg.HasExternalAgent,
278278
arg.Shared,
279279
arg.SharedWithUserID,
280+
arg.SharedWithGroupID,
280281
arg.RequesterID,
281282
arg.Offset,
282283
arg.Limit,

‎coderd/database/queries.sql.go‎

Lines changed: 13 additions & 5 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/workspaces.sql‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,12 @@ WHERE
390390
workspaces.user_acl ? (@shared_with_user_id :: uuid) ::text
391391
ELSE true
392392
END
393+
-- Filter by shared_with_group_id
394+
AND CASE
395+
WHEN @shared_with_group_id :: uuid!='00000000-0000-0000-0000-000000000000'::uuid THEN
396+
workspaces.group_acl ? (@shared_with_group_id :: uuid) ::text
397+
ELSE true
398+
END
393399
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
394400
-- @authorize_filter
395401
), filtered_workspaces_orderAS (

‎coderd/searchquery/search.go‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ func Workspaces(ctx context.Context, db database.Store, query string, page coder
227227
filter.OrganizationID=parseOrganization(ctx,db,parser,values,"organization")
228228
filter.Shared=parser.NullableBoolean(values, sql.NullBool{},"shared")
229229
filter.SharedWithUserID=parseUser(ctx,db,parser,values,"shared_with_user")
230+
filter.SharedWithGroupID=parseGroup(ctx,db,parser,values,"shared_with_group")
230231

231232
typeparamMatchstruct {
232233
namestring
@@ -383,6 +384,65 @@ func parseUser(ctx context.Context, db database.Store, parser *httpapi.QueryPara
383384
})
384385
}
385386

387+
// Attempts to parse the filter into either the group ID, or the organization
388+
// name and group name in the format of either <group name> which assumes the
389+
// user's default, or <organization name>/<group name> returning the fetched
390+
// group's ID.
391+
funcparseGroup(ctx context.Context,db database.Store,parser*httpapi.QueryParamParser,vals url.Values,queryParamstring) uuid.UUID {
392+
returnhttpapi.ParseCustom(parser,vals,uuid.Nil,queryParam,func(vstring) (uuid.UUID,error) {
393+
ifv=="" {
394+
returnuuid.Nil,nil
395+
}
396+
groupID,err:=uuid.Parse(v)
397+
iferr==nil {
398+
returngroupID,nil
399+
}
400+
401+
vargroupNamestring
402+
varorg database.Organization
403+
parts:=strings.Split(v,"/")
404+
switchlen(parts) {
405+
case1:
406+
dbOrg,err:=db.GetDefaultOrganization(ctx)
407+
iferr!=nil {
408+
returnuuid.Nil,xerrors.New("fetching default organization")
409+
}
410+
org=dbOrg
411+
groupName=parts[0]
412+
case2:
413+
orgName:=parts[0]
414+
iferr:=codersdk.NameValid(orgName);err!=nil {
415+
returnuuid.Nil,xerrors.Errorf("invalid organization name %w",err)
416+
}
417+
dbOrg,err:=db.GetOrganizationByName(ctx, database.GetOrganizationByNameParams{
418+
Name:orgName,
419+
})
420+
iferr!=nil {
421+
returnuuid.Nil,xerrors.Errorf("organization %q either does not exist, or you are unauthorized to view it",orgName)
422+
}
423+
org=dbOrg
424+
425+
groupName=parts[1]
426+
427+
default:
428+
returnuuid.Nil,xerrors.New("invalid organization or group name, the filter must be in the pattern of <organization name>/<group name>")
429+
}
430+
431+
iferr:=codersdk.GroupNameValid(groupName);err!=nil {
432+
returnuuid.Nil,xerrors.Errorf("invalid organization name %w",err)
433+
}
434+
435+
group,err:=db.GetGroupByOrgAndName(ctx, database.GetGroupByOrgAndNameParams{
436+
OrganizationID:org.ID,
437+
Name:groupName,
438+
})
439+
iferr!=nil {
440+
returnuuid.Nil,xerrors.Errorf("group %q either does not exist, does not belong to the organization %q, or you are unauthorized to view it",groupName,org.Name)
441+
}
442+
returngroup.ID,nil
443+
})
444+
}
445+
386446
// splitQueryParameterByDelimiter takes a query string and splits it into the individual elements
387447
// of the query. Each element is separated by a delimiter. All quoted strings are
388448
// kept as a single element.

‎coderd/searchquery/search_test.go‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,59 @@ func TestSearchWorkspace(t *testing.T) {
337337
SharedWithUserID:uuid.MustParse("3dd8b1b8-dff5-4b22-8ae9-c243ca136ecf"),
338338
},
339339
},
340+
{
341+
Name:"SharedWithGroupDefaultOrg",
342+
Query:"shared_with_group:wibble",
343+
Setup:func(t*testing.T,db database.Store) {
344+
org,err:=db.GetOrganizationByName(t.Context(), database.GetOrganizationByNameParams{
345+
Name:"coder",
346+
})
347+
require.NoError(t,err)
348+
349+
dbgen.Group(t,db, database.Group{
350+
ID:uuid.MustParse("590f1006-15e6-4b21-a6e1-92e33af8a5c3"),
351+
Name:"wibble",
352+
OrganizationID:org.ID,
353+
})
354+
},
355+
Expected: database.GetWorkspacesParams{
356+
SharedWithGroupID:uuid.MustParse("590f1006-15e6-4b21-a6e1-92e33af8a5c3"),
357+
},
358+
},
359+
{
360+
Name:"SharedWithGroupInOrg",
361+
Query:"shared_with_group:wibble/wobble",
362+
Setup:func(t*testing.T,db database.Store) {
363+
org:=dbgen.Organization(t,db, database.Organization{
364+
ID:uuid.MustParse("dbeb1bd5-dce6-459c-ab7b-b7f8b9b10467"),
365+
Name:"wibble",
366+
})
367+
dbgen.Group(t,db, database.Group{
368+
ID:uuid.MustParse("3c831688-0a5a-45a2-a796-f7648874df34"),
369+
Name:"wobble",
370+
OrganizationID:org.ID,
371+
})
372+
},
373+
Expected: database.GetWorkspacesParams{
374+
SharedWithGroupID:uuid.MustParse("3c831688-0a5a-45a2-a796-f7648874df34"),
375+
},
376+
},
377+
{
378+
Name:"SharedWithGroupID",
379+
Query:"shared_with_group:a7d1ba00-53c7-4aa6-92ea-83157dd57480",
380+
Setup:func(t*testing.T,db database.Store) {
381+
org:=dbgen.Organization(t,db, database.Organization{
382+
ID:uuid.MustParse("8606620f-fee4-4c4e-83ba-f42db804139a"),
383+
})
384+
dbgen.Group(t,db, database.Group{
385+
ID:uuid.MustParse("a7d1ba00-53c7-4aa6-92ea-83157dd57480"),
386+
OrganizationID:org.ID,
387+
})
388+
},
389+
Expected: database.GetWorkspacesParams{
390+
SharedWithGroupID:uuid.MustParse("a7d1ba00-53c7-4aa6-92ea-83157dd57480"),
391+
},
392+
},
340393

341394
// Failures
342395
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp