blob: c3d6c5eeedaa584e9d880bd6778bf083e10367bd [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Measured methods for syncgroup management.
package measure
import (
"fmt"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/security/access"
wire "v.io/v23/services/syncbase"
"v.io/v23/syncbase"
"v.io/x/sensorlog/internal/config"
"v.io/x/sensorlog/internal/sbmodel"
"v.io/x/sensorlog/internal/sbmodel/keyutil"
"v.io/x/sensorlog/internal/sbutil"
)
// InitSyncgroup creates the syncgroup for the measuring device devId, giving
// full configuration access to admin. The syncgroup uses sgPublishSb and
// sgMountTables for publishing (create/join) and syncing, respectively.
// InitSyncgroup must not be called concurrently for the same devId, or
// retried with different parameters for the same devId, otherwise behaviour
// is unspecified.
// TODO(ivanpi): Remove Resolve permissions when v.io/i/1110 is fixed.
func InitSyncgroup(ctx *context.T, db syncbase.Database, devId, admin, sgPublishSb string, sgMountTables []string) error {
if err := keyutil.ValidateId(devId); err != nil {
return fmt.Errorf("invalid devId: %v", err)
}
sgId := wire.Id{Name: config.SyncgroupName(devId), Blessing: "blessing"}
// Check for syncgroup. If it already exists, we have nothing to do.
if sgs, err := db.ListSyncgroups(ctx); err != nil {
return err
} else {
for _, sg := range sgs {
if sg == sgId {
return nil
}
}
}
// Both measured and admin client have full permissions on the syncgroup.
sgAcl := access.Permissions{}
sbutil.AddPermsForPrincipal(&sgAcl, v23.GetPrincipal(ctx), access.Read, access.Admin)
sbutil.AddPermsForPattern(&sgAcl, admin, access.Read, access.Admin)
// Maps all syncgroup collections to ACLs.
collSpec := make(map[wire.Id]access.Permissions)
// StreamDef : <devId>
// Note that since the SyncgroupSpec takes collections, we drop the devId.
// Admin client has full permissions, measured drops to readonly.
aclStreamDef := access.Permissions{}
sbutil.AddPermsForPrincipal(&aclStreamDef, v23.GetPrincipal(ctx), access.Resolve, access.Read)
sbutil.AddPermsForPattern(&aclStreamDef, admin, access.Resolve, access.Read, access.Write, access.Admin)
collSpec[sbmodel.CollectionId(&sbmodel.KStreamDef{})] = aclStreamDef
// DataPoint : <devId>
// Note that since the SyncgroupSpec takes collections, we drop the devId.
// Admin client has full permissions, measured drops to read/write.
aclDataPoint := access.Permissions{}
sbutil.AddPermsForPrincipal(&aclDataPoint, v23.GetPrincipal(ctx), access.Resolve, access.Read, access.Write)
sbutil.AddPermsForPattern(&aclDataPoint, admin, access.Resolve, access.Read, access.Write, access.Admin)
collSpec[sbmodel.CollectionId(&sbmodel.KDataPoint{})] = aclDataPoint
var collections []wire.Id
// Apply prefix ACLs to all syncgroup prefixes.
// TODO(ivanpi): Prefix ACLs have been removed, use collection ACLs.
for coll, _ := range collSpec {
collections = append(collections, coll)
}
sgSpec := wire.SyncgroupSpec{
Description: fmt.Sprintf("measured-main-%s", devId),
Perms: sgAcl,
Collections: collections,
MountTables: sgMountTables,
}
sgMemberInfo := wire.SyncgroupMemberInfo{SyncPriority: config.SyncPriority}
return db.SyncgroupForId(sgId).Create(ctx, sgSpec, sgMemberInfo)
}