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

Use implicit field mask paths in IS #249

Merged
merged 4 commits into from
Mar 8, 2019
Merged
Changes from all commits
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
13 changes: 1 addition & 12 deletions cmd/ttn-lw-cli/commands/applications.go
Original file line number Diff line number Diff line change
@@ -68,10 +68,6 @@ var (
Short: "List applications",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectApplicationFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
@@ -93,10 +89,7 @@ var (
Short: "Search for applications",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectApplicationFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

req := getSearchEntitiesRequest(cmd.Flags())
req.FieldMask.Paths = paths

@@ -122,10 +115,6 @@ var (
return errNoApplicationID
}
paths := util.SelectFieldMask(cmd.Flags(), selectApplicationFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
13 changes: 1 addition & 12 deletions cmd/ttn-lw-cli/commands/clients.go
Original file line number Diff line number Diff line change
@@ -68,10 +68,6 @@ var (
Short: "List clients",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectClientFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
@@ -93,10 +89,7 @@ var (
Short: "Search for clients",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectClientFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

req := getSearchEntitiesRequest(cmd.Flags())
req.FieldMask.Paths = paths

@@ -122,10 +115,6 @@ var (
return errNoClientID
}
paths := util.SelectFieldMask(cmd.Flags(), selectClientFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
8 changes: 0 additions & 8 deletions cmd/ttn-lw-cli/commands/end_devices.go
Original file line number Diff line number Diff line change
@@ -131,10 +131,6 @@ var (
return errNoApplicationID
}
paths := util.SelectFieldMask(cmd.Flags(), selectEndDeviceListFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
@@ -161,10 +157,6 @@ var (
return err
}
paths := util.SelectFieldMask(cmd.Flags(), selectEndDeviceFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

isPaths, nsPaths, asPaths, jsPaths := splitEndDeviceGetPaths(paths...)

2 changes: 0 additions & 2 deletions cmd/ttn-lw-cli/commands/flags.go
Original file line number Diff line number Diff line change
@@ -23,8 +23,6 @@ import (
"go.thethings.network/lorawan-stack/pkg/ttnpb"
)

var defaultGetPaths = []string{"name"}

func collaboratorFlags() *pflag.FlagSet {
flagSet := &pflag.FlagSet{}
flagSet.String("user-id", "", "")
13 changes: 1 addition & 12 deletions cmd/ttn-lw-cli/commands/gateways.go
Original file line number Diff line number Diff line change
@@ -84,10 +84,6 @@ var (
Short: "List gateways",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectGatewayFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
@@ -109,10 +105,7 @@ var (
Short: "Search for gateways",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectGatewayFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

req := getSearchEntitiesRequest(cmd.Flags())
req.FieldMask.Paths = paths

@@ -138,10 +131,6 @@ var (
return err
}
paths := util.SelectFieldMask(cmd.Flags(), selectGatewayFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
13 changes: 1 addition & 12 deletions cmd/ttn-lw-cli/commands/organizations.go
Original file line number Diff line number Diff line change
@@ -68,10 +68,6 @@ var (
Short: "List organizations",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectOrganizationFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
@@ -93,10 +89,7 @@ var (
Short: "Search for organizations",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectOrganizationFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

req := getSearchEntitiesRequest(cmd.Flags())
req.FieldMask.Paths = paths

@@ -122,10 +115,6 @@ var (
return errNoOrganizationID
}
paths := util.SelectFieldMask(cmd.Flags(), selectOrganizationFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
9 changes: 1 addition & 8 deletions cmd/ttn-lw-cli/commands/users.go
Original file line number Diff line number Diff line change
@@ -71,10 +71,7 @@ var (
Short: "Search for users",
RunE: func(cmd *cobra.Command, args []string) error {
paths := util.SelectFieldMask(cmd.Flags(), selectUserFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

req := getSearchEntitiesRequest(cmd.Flags())
req.FieldMask.Paths = paths

@@ -100,10 +97,6 @@ var (
return errNoUserID
}
paths := util.SelectFieldMask(cmd.Flags(), selectUserFlags)
if len(paths) == 0 {
logger.Warnf("No fields selected, selecting %v", defaultGetPaths)
paths = append(paths, defaultGetPaths...)
}

is, err := api.Dial(ctx, config.IdentityServerAddress)
if err != nil {
12 changes: 10 additions & 2 deletions pkg/identityserver/application_registry.go
Original file line number Diff line number Diff line change
@@ -83,6 +83,7 @@ func (is *IdentityServer) getApplication(ctx context.Context, req *ttnpb.GetAppl
if err = is.RequireAuthenticated(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ApplicationFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary?
Why not just set this to getPaths if len(req.FieldMask.Paths) == 0?
Basically the same question for all other invocations - I really don't get what's going on here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getPaths contains the fields that are implicitly part of the field mask, so they are always added to the field mask in the request, if it doesn't already contain them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but there's no harm in adding a field twice - you can just append the fields - we do the same in JS/NS and AS AFAIK.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to construct the slice of required fields, Set registry endpoint in NS constructs a gets and sets:

gets := append(req.FieldMask.Paths[:0:0], req.FieldMask.Paths...)
if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.device_class") {
gets = append(gets,
"mac_state.current_parameters",
"mac_state.desired_parameters",
"queued_application_downlinks",
)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the NS/JS. In the IS we prefer to have paths in the field mask only once.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then why not ttnpb.EnsureFieldpaths(paths []string, ensure ...string) []string?
You pass the existing fieldmask and the paths you want to add if missing.
You don't need 4 arguments for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no ttnpb.EnsureFieldPaths, I want to combine this with the allowed paths, I want to be able to specify paths that need to be deleted if present, and finally, I want to do it in a single pass instead of combining EnsureFieldPaths, EnsureNotFieldPaths, IntersectFieldPaths, UniqueFieldPaths.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We have API layer middleware, which should validate that fields that should not be present are not present.
  2. Invalid fieldpaths, which still could get through should be validated explicitly and if present - throw an error.

RPC implementation simply should not delete anything passed to it. Cleaning and validation belongs to the API layer middleware. RPC should simply upsert the required fields.

if err = rights.RequireApplication(ctx, req.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_INFO); err != nil {
if ttnpb.HasOnlyAllowedFields(req.FieldMask.Paths, ttnpb.PublicApplicationFields...) {
defer func() { app = app.PublicSafe() }()
@@ -110,6 +111,7 @@ func (is *IdentityServer) getApplication(ctx context.Context, req *ttnpb.GetAppl
}

func (is *IdentityServer) listApplications(ctx context.Context, req *ttnpb.ListApplicationsRequest) (apps *ttnpb.Applications, err error) {
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ApplicationFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
var appRights map[string]*ttnpb.Rights
if req.Collaborator == nil {
callerRights, _, err := is.getRights(ctx)
@@ -186,8 +188,14 @@ func (is *IdentityServer) updateApplication(ctx context.Context, req *ttnpb.Upda
if err = rights.RequireApplication(ctx, req.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_SETTINGS_BASIC); err != nil {
return nil, err
}
if err := validateContactInfo(req.Application.ContactInfo); err != nil {
return nil, err
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ApplicationFieldPathsNested, req.FieldMask.Paths, nil, getPaths)
if len(req.FieldMask.Paths) == 0 {
req.FieldMask.Paths = updatePaths
}
if ttnpb.HasAnyField(req.FieldMask.Paths, "contact_info") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not evaluate to true if any of the child paths in contact_info, e.g. contact_info.contact_type is set(https://github.com/TheThingsNetwork/lorawan-stack/blob/master/api/contact_info.proto#L45)
Is that expected behavior?
Additionally, it seems like contact_info is not part of allowed fieldmasks of any PRC at https://github.com/TheThingsNetwork/lorawan-stack/blob/9e35fc3e7bf1ce817076ed39a916914e1b739de7/pkg/ttnpb/field_mask_validation.go at all.
How is this supposed to work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. contact_info is a slice. Field mask paths don't recurse into slices.
  2. EndDevice doesn't have a contact_info field. For applications and other entities, the allowed paths come from ttnpb.ApplicationFieldPathsNested etc.

if err := validateContactInfo(req.Application.ContactInfo); err != nil {
return nil, err
}
}
err = is.withDatabase(ctx, func(db *gorm.DB) (err error) {
app, err = store.GetApplicationStore(db).UpdateApplication(ctx, &req.Application, &req.FieldMask)
12 changes: 10 additions & 2 deletions pkg/identityserver/client_registry.go
Original file line number Diff line number Diff line change
@@ -111,6 +111,7 @@ func (is *IdentityServer) getClient(ctx context.Context, req *ttnpb.GetClientReq
if err = is.RequireAuthenticated(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ClientFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
if err = rights.RequireClient(ctx, req.ClientIdentifiers, ttnpb.RIGHT_CLIENT_ALL); err != nil {
if ttnpb.HasOnlyAllowedFields(req.FieldMask.Paths, ttnpb.PublicClientFields...) {
defer func() { cli = cli.PublicSafe() }()
@@ -138,6 +139,7 @@ func (is *IdentityServer) getClient(ctx context.Context, req *ttnpb.GetClientReq
}

func (is *IdentityServer) listClients(ctx context.Context, req *ttnpb.ListClientsRequest) (clis *ttnpb.Clients, err error) {
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ClientFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
var cliRights map[string]*ttnpb.Rights
if req.Collaborator == nil {
callerRights, _, err := is.getRights(ctx)
@@ -218,8 +220,14 @@ func (is *IdentityServer) updateClient(ctx context.Context, req *ttnpb.UpdateCli
if err = rights.RequireClient(ctx, req.ClientIdentifiers, ttnpb.RIGHT_CLIENT_ALL); err != nil {
return nil, err
}
if err := validateContactInfo(req.Client.ContactInfo); err != nil {
return nil, err
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ClientFieldPathsNested, req.FieldMask.Paths, nil, getPaths)
if len(req.FieldMask.Paths) == 0 {
req.FieldMask.Paths = updatePaths
}
if ttnpb.HasAnyField(req.FieldMask.Paths, "contact_info") {
if err := validateContactInfo(req.Client.ContactInfo); err != nil {
return nil, err
}
}
updatedByAdmin := is.UniversalRights(ctx).IncludesAll(ttnpb.RIGHT_USER_ALL)

6 changes: 6 additions & 0 deletions pkg/identityserver/end_device_registry.go
Original file line number Diff line number Diff line change
@@ -57,6 +57,7 @@ func (is *IdentityServer) getEndDevice(ctx context.Context, req *ttnpb.GetEndDev
if err = rights.RequireApplication(ctx, req.EndDeviceIdentifiers.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_DEVICES_READ); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.EndDeviceFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
err = is.withDatabase(ctx, func(db *gorm.DB) (err error) {
dev, err = store.GetEndDeviceStore(db).GetEndDevice(ctx, &req.EndDeviceIdentifiers, &req.FieldMask)
return err
@@ -71,6 +72,7 @@ func (is *IdentityServer) listEndDevices(ctx context.Context, req *ttnpb.ListEnd
if err = rights.RequireApplication(ctx, req.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_DEVICES_READ); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.EndDeviceFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
var total uint64
ctx = store.SetTotalCount(ctx, &total)
defer func() {
@@ -96,6 +98,10 @@ func (is *IdentityServer) updateEndDevice(ctx context.Context, req *ttnpb.Update
if err = rights.RequireApplication(ctx, req.EndDeviceIdentifiers.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_DEVICES_WRITE); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.EndDeviceFieldPathsNested, req.FieldMask.Paths, nil, getPaths)
if len(req.FieldMask.Paths) == 0 {
req.FieldMask.Paths = updatePaths
}
err = is.withDatabase(ctx, func(db *gorm.DB) (err error) {
dev, err = store.GetEndDeviceStore(db).UpdateEndDevice(ctx, &req.EndDevice, &req.FieldMask)
return err
12 changes: 10 additions & 2 deletions pkg/identityserver/gateway_registry.go
Original file line number Diff line number Diff line change
@@ -83,6 +83,7 @@ func (is *IdentityServer) getGateway(ctx context.Context, req *ttnpb.GetGatewayR
if err = is.RequireAuthenticated(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.GatewayFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
if err = rights.RequireGateway(ctx, req.GatewayIdentifiers, ttnpb.RIGHT_GATEWAY_INFO); err != nil {
if ttnpb.HasOnlyAllowedFields(req.FieldMask.Paths, ttnpb.PublicGatewayFields...) {
defer func() { gtw = gtw.PublicSafe() }()
@@ -130,6 +131,7 @@ func (is *IdentityServer) getGatewayIdentifiersForEUI(ctx context.Context, req *
}

func (is *IdentityServer) listGateways(ctx context.Context, req *ttnpb.ListGatewaysRequest) (gtws *ttnpb.Gateways, err error) {
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.GatewayFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
var gtwRights map[string]*ttnpb.Rights
if req.Collaborator == nil {
callerRights, _, err := is.getRights(ctx)
@@ -206,8 +208,14 @@ func (is *IdentityServer) updateGateway(ctx context.Context, req *ttnpb.UpdateGa
if err = rights.RequireGateway(ctx, req.GatewayIdentifiers, ttnpb.RIGHT_GATEWAY_SETTINGS_BASIC); err != nil {
return nil, err
}
if err := validateContactInfo(req.Gateway.ContactInfo); err != nil {
return nil, err
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.GatewayFieldPathsNested, req.FieldMask.Paths, nil, getPaths)
if len(req.FieldMask.Paths) == 0 {
req.FieldMask.Paths = updatePaths
}
if ttnpb.HasAnyField(req.FieldMask.Paths, "contact_info") {
if err := validateContactInfo(req.Gateway.ContactInfo); err != nil {
return nil, err
}
}
err = is.withDatabase(ctx, func(db *gorm.DB) (err error) {
gtw, err = store.GetGatewayStore(db).UpdateGateway(ctx, &req.Gateway, &req.FieldMask)
12 changes: 10 additions & 2 deletions pkg/identityserver/organization_registry.go
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ func (is *IdentityServer) getOrganization(ctx context.Context, req *ttnpb.GetOrg
if err = is.RequireAuthenticated(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.OrganizationFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
if err = rights.RequireOrganization(ctx, req.OrganizationIdentifiers, ttnpb.RIGHT_ORGANIZATION_INFO); err != nil {
if ttnpb.HasOnlyAllowedFields(req.FieldMask.Paths, ttnpb.PublicOrganizationFields...) {
defer func() { org = org.PublicSafe() }()
@@ -111,6 +112,7 @@ func (is *IdentityServer) getOrganization(ctx context.Context, req *ttnpb.GetOrg
}

func (is *IdentityServer) listOrganizations(ctx context.Context, req *ttnpb.ListOrganizationsRequest) (orgs *ttnpb.Organizations, err error) {
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.OrganizationFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
var orgRights map[string]*ttnpb.Rights
if req.Collaborator == nil {
callerRights, _, err := is.getRights(ctx)
@@ -185,8 +187,14 @@ func (is *IdentityServer) updateOrganization(ctx context.Context, req *ttnpb.Upd
if err = rights.RequireOrganization(ctx, req.OrganizationIdentifiers, ttnpb.RIGHT_ORGANIZATION_SETTINGS_BASIC); err != nil {
return nil, err
}
if err := validateContactInfo(req.Organization.ContactInfo); err != nil {
return nil, err
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.OrganizationFieldPathsNested, req.FieldMask.Paths, nil, getPaths)
if len(req.FieldMask.Paths) == 0 {
req.FieldMask.Paths = updatePaths
}
if ttnpb.HasAnyField(req.FieldMask.Paths, "contact_info") {
if err := validateContactInfo(req.Organization.ContactInfo); err != nil {
return nil, err
}
}
err = is.withDatabase(ctx, func(db *gorm.DB) (err error) {
org, err = store.GetOrganizationStore(db).UpdateOrganization(ctx, &req.Organization, &req.FieldMask)
5 changes: 5 additions & 0 deletions pkg/identityserver/registry_search.go
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ func (rs *registrySearch) SearchApplications(ctx context.Context, req *ttnpb.Sea
if err := rs.SearchAllowed(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ApplicationFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
res := &ttnpb.Applications{}
err := rs.withDatabase(ctx, func(db *gorm.DB) error {
entityIDs, err := store.GetEntitySearch(db).FindEntities(ctx, req, "application")
@@ -78,6 +79,7 @@ func (rs *registrySearch) SearchClients(ctx context.Context, req *ttnpb.SearchEn
if err := rs.SearchAllowed(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ClientFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
res := &ttnpb.Clients{}
err := rs.withDatabase(ctx, func(db *gorm.DB) error {
entityIDs, err := store.GetEntitySearch(db).FindEntities(ctx, req, "client")
@@ -110,6 +112,7 @@ func (rs *registrySearch) SearchGateways(ctx context.Context, req *ttnpb.SearchE
if err := rs.SearchAllowed(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.GatewayFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
res := &ttnpb.Gateways{}
err := rs.withDatabase(ctx, func(db *gorm.DB) error {
entityIDs, err := store.GetEntitySearch(db).FindEntities(ctx, req, "gateway")
@@ -142,6 +145,7 @@ func (rs *registrySearch) SearchOrganizations(ctx context.Context, req *ttnpb.Se
if err := rs.SearchAllowed(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.OrganizationFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
res := &ttnpb.Organizations{}
err := rs.withDatabase(ctx, func(db *gorm.DB) error {
entityIDs, err := store.GetEntitySearch(db).FindEntities(ctx, req, "organization")
@@ -174,6 +178,7 @@ func (rs *registrySearch) SearchUsers(ctx context.Context, req *ttnpb.SearchEnti
if err := rs.SearchAllowed(ctx); err != nil {
return nil, err
}
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.UserFieldPathsNested, req.FieldMask.Paths, getPaths, nil)
res := &ttnpb.Users{}
err := rs.withDatabase(ctx, func(db *gorm.DB) error {
entityIDs, err := store.GetEntitySearch(db).FindEntities(ctx, req, "user")
Loading