Skip to content

Commit a8379d7

Browse files
committed
handle the go side
Signed-off-by: Robert Landers <landers.robert@gmail.com>
1 parent a68af98 commit a8379d7

File tree

9 files changed

+161
-48
lines changed

9 files changed

+161
-48
lines changed

cli/auth/createPermissions.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type CreatePermissions struct {
2525
Limits Limits `json:"limits"`
2626
Users []UserId `json:"users"`
2727
Roles []Role `json:"roles"`
28+
FromId []string `json:"from"`
29+
FromType []string `json:"from-type"`
2830
TimeToLive uint64 `json:"ttl"`
2931
}
3032

cli/auth/resource.go

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,16 @@ import (
4646
// - WantTo: checks if the current user can perform the given operation on the resource.
4747
// - Grant: grants a share to the resource.
4848
type Resource struct {
49-
Owners map[UserId]struct{} `json:"owner"`
50-
Shares []Share `json:"Shares"`
51-
Mode Mode `json:"mode"`
52-
mu sync.RWMutex
53-
kv jetstream.KeyValue
54-
id *ids.StateId
55-
Expires time.Time
56-
revision uint64
49+
Owners map[UserId]struct{} `json:"owner"`
50+
Shares []Share `json:"Shares"`
51+
Mode Mode `json:"mode"`
52+
mu sync.RWMutex
53+
kv jetstream.KeyValue
54+
id *ids.StateId
55+
AllowedFromTypes []string `json:"allowed_from_types"`
56+
AllowedFromIds []*ids.StateId `json:"allowed_from_ids"`
57+
Expires time.Time
58+
revision uint64
5759
}
5860

5961
// NewResourcePermissions creates a new Resource with the specified owner and mode. If the owner is nil, the resource
@@ -101,7 +103,7 @@ func (r *Resource) ShareOwnership(newUser UserId, currentUser *User, keepPermiss
101103

102104
r.mu.Lock()
103105
defer r.mu.Unlock()
104-
if currentUser != nil && !keepPermissions {
106+
if !keepPermissions {
105107
delete(r.Owners, currentUser.UserId)
106108
}
107109
r.Owners[newUser] = struct{}{}
@@ -123,13 +125,13 @@ func (r *Resource) ApplyPerms(id *ids.StateId, ctx context.Context, logger *zap.
123125
}
124126

125127
// CanCreate Load permissions from cache if available, otherwise fetch from external source
126-
func (r *Resource) CanCreate(id *ids.StateId, ctx context.Context, logger *zap.Logger) bool {
128+
func (r *Resource) CanCreate(id *ids.StateId, from *ids.StateId, ctx context.Context, logger *zap.Logger) bool {
127129
perms, err := r.getOrCreatePermissions(id, ctx, logger)
128130
if err != nil {
129131
logger.Error("failed to create permissions", zap.Error(err))
130132
return false
131133
}
132-
return r.isUserPermitted(perms, ctx)
134+
return r.isUserPermitted(perms, ctx) && r.AllowedFrom(from)
133135
}
134136

135137
func (r *Resource) getOrCreatePermissions(id *ids.StateId, ctx context.Context, logger *zap.Logger) (CreatePermissions, error) {
@@ -158,6 +160,10 @@ func (r *Resource) getOrCreatePermissions(id *ids.StateId, ctx context.Context,
158160

159161
func (r *Resource) isUserPermitted(perms CreatePermissions, ctx context.Context) bool {
160162
r.Mode = perms.Mode
163+
for _, p := range perms.FromId {
164+
r.AllowedFromIds = append(r.AllowedFromIds, ids.ParseStateId(p))
165+
}
166+
r.AllowedFromTypes = perms.FromType
161167
r.Expires = time.Now().Add(time.Duration(perms.TimeToLive) * time.Nanosecond)
162168
switch perms.Mode {
163169
case AnonymousMode:
@@ -219,6 +225,29 @@ func (r *Resource) IsOwner(ctx context.Context) bool {
219225
return false
220226
}
221227

228+
func (r *Resource) AllowedFrom(from *ids.StateId) bool {
229+
if len(r.AllowedFromIds) == 0 && len(r.AllowedFromTypes) == 0 {
230+
return true
231+
}
232+
233+
for _, id := range r.AllowedFromIds {
234+
if id.Kind == from.Kind && id.Id == from.Id {
235+
return true
236+
}
237+
}
238+
239+
for _, t := range r.AllowedFromTypes {
240+
if ent, found := from.ToEntityId(); found && ent.Name == t {
241+
return true
242+
}
243+
if orch, found := from.ToOrchestrationId(); found && orch.InstanceId == t {
244+
return true
245+
}
246+
}
247+
248+
return false
249+
}
250+
222251
// WantTo determines if the user is able to perform the specified operation on the resource.
223252
// It accepts the operation to be performed and the context containing the user information.
224253
// If the resource mode is set to AnonymousMode, it allows any operation.

cli/auth/resourceManager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func GetResourceManager(ctx context.Context, stream jetstream.JetStream) *Resour
4747

4848
// DiscoverResource is a method of the ResourceManager struct that is responsible for discovering a resource based on
4949
// the provided context, state ID, logger, and preventCreation flag
50-
func (r *ResourceManager) DiscoverResource(ctx context.Context, id *ids.StateId, logger *zap.Logger, preventCreation bool) (*Resource, error) {
50+
func (r *ResourceManager) DiscoverResource(ctx context.Context, id *ids.StateId, from *ids.StateId, logger *zap.Logger, preventCreation bool) (*Resource, error) {
5151
currentUser, _ := ctx.Value(appcontext.CurrentUserKey).(*User)
5252

5353
data, err := r.kv.Get(ctx, id.ToSubject().String())
@@ -58,7 +58,7 @@ func (r *ResourceManager) DiscoverResource(ctx context.Context, id *ids.StateId,
5858
resource.kv = r.kv
5959
resource.id = id
6060
resource.revision = 0
61-
if resource.CanCreate(id, ctx, logger) {
61+
if resource.CanCreate(id, from, ctx, logger) {
6262
err = resource.Update(ctx, logger)
6363
if err != nil {
6464
return nil, err

cli/ids/id.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ const (
1414
Orchestration IdKind = "orchestration"
1515
)
1616

17+
var ApiSource *StateId = &StateId{
18+
Id: "--api--",
19+
Kind: "--api--",
20+
}
21+
1722
// subjects
1823

1924
type Subject struct {
@@ -73,12 +78,12 @@ func (id StateId) String() string {
7378
return fmt.Sprintf("%s:%s", id.Kind, id.Id)
7479
}
7580

76-
func (id StateId) Name() string {
81+
func (id StateId) Name() IdKind {
7782
if before, _, found := strings.Cut(id.Id, ":"); found {
78-
return before
83+
return IdKind(before)
7984
}
8085

81-
return string(Activity)
86+
return Activity
8287
}
8388

8489
func (id StateId) ToEntityId() (*EntityId, bool) {
@@ -174,6 +179,6 @@ func (id *OrchestrationId) ToStateId() *StateId {
174179
}
175180

176181
type StateId struct {
177-
Id string
178-
Kind IdKind
182+
Id string `json:"id,omitempty"`
183+
Kind IdKind `json:"kind,omitempty"`
179184
}

cli/lib/api.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
262262
defer cancel()
263263

264264
rm := auth.GetResourceManager(ctx, js)
265-
res, err := rm.DiscoverResource(ctx, id, logger, true)
265+
res, err := rm.DiscoverResource(ctx, id, ids.ApiSource, logger, true)
266266
if err != nil {
267267
logger.Error("DiscoverResource", zap.Error(err))
268268
panic(err)
@@ -312,7 +312,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
312312
}
313313

314314
if deleteAfter {
315-
resource, err := rm.DiscoverResource(ctx, id, logger, false)
315+
resource, err := rm.DiscoverResource(ctx, id, ids.ApiSource, logger, false)
316316
if err != nil {
317317
logger.Error("Unable to delete resource", zap.Error(err))
318318
http.Error(writer, "Internal Server Error", http.StatusInternalServerError)
@@ -354,7 +354,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
354354
return
355355
}
356356

357-
r, err := rm.DiscoverResource(ctx, stateId, logger, true)
357+
r, err := rm.DiscoverResource(ctx, stateId, ids.ApiSource, logger, true)
358358
if err != nil {
359359
logger.Error("Failed to discover resource", zap.Error(err))
360360
http.Error(writer, "Not Found", http.StatusNotFound)
@@ -430,7 +430,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
430430
return
431431
}
432432

433-
r, err := rm.DiscoverResource(ctx, stateId, logger, true)
433+
r, err := rm.DiscoverResource(ctx, stateId, ids.ApiSource, logger, true)
434434
if err != nil {
435435
logger.Error("Failed to discover resource", zap.Error(err))
436436
http.Error(writer, "", http.StatusNotFound)
@@ -485,7 +485,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
485485
return
486486
}
487487

488-
r, err := rm.DiscoverResource(ctx, stateId, logger, true)
488+
r, err := rm.DiscoverResource(ctx, stateId, ids.ApiSource, logger, true)
489489
if err != nil {
490490
logger.Error("Failed to discover resource", zap.Error(err))
491491
http.Error(writer, "", http.StatusNotFound)
@@ -571,7 +571,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
571571
}
572572

573573
logger.Debug("Delete entity", zap.String("id", id.String()))
574-
rs, err := rm.DiscoverResource(ctx, id.ToStateId(), logger, true)
574+
rs, err := rm.DiscoverResource(ctx, id.ToStateId(), ids.ApiSource, logger, true)
575575
if err != nil {
576576
logger.Error("Failed to discover resource", zap.Error(err))
577577
http.Error(writer, "Not Found", http.StatusNotFound)
@@ -682,7 +682,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
682682
return
683683
}
684684

685-
r, err := rm.DiscoverResource(ctx, stateId, logger, true)
685+
r, err := rm.DiscoverResource(ctx, stateId, ids.ApiSource, logger, true)
686686
if err != nil {
687687
logger.Error("Failed to discover resource", zap.Error(err))
688688
http.Error(writer, "Not Found", http.StatusNotFound)
@@ -758,7 +758,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
758758
return
759759
}
760760

761-
r, err := rm.DiscoverResource(ctx, stateId, logger, true)
761+
r, err := rm.DiscoverResource(ctx, stateId, ids.ApiSource, logger, true)
762762
if err != nil {
763763
logger.Error("Failed to discover resource", zap.Error(err))
764764
http.Error(writer, "", http.StatusNotFound)
@@ -813,7 +813,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
813813
return
814814
}
815815

816-
r, err := rm.DiscoverResource(ctx, stateId, logger, true)
816+
r, err := rm.DiscoverResource(ctx, stateId, ids.ApiSource, logger, true)
817817
if err != nil {
818818
logger.Error("Failed to discover resource", zap.Error(err))
819819
http.Error(writer, "", http.StatusNotFound)
@@ -878,7 +878,7 @@ func Startup(ctx context.Context, js jetstream.JetStream, logger *zap.Logger, po
878878
return
879879
}
880880

881-
rs, err := rm.DiscoverResource(ctx, id.ToStateId(), logger, true)
881+
rs, err := rm.DiscoverResource(ctx, id.ToStateId(), ids.ApiSource, logger, true)
882882
if err != nil {
883883
logger.Error("Failed to discover a resource for deletion", zap.Error(err))
884884
http.Error(writer, "Not Found", http.StatusNotFound)
@@ -1032,7 +1032,7 @@ func authorize(
10321032
logger.Info("Authenticating with user", zap.Any("user", user))
10331033
ctx = auth.DecorateContextWithUser(ctx, user)
10341034
}
1035-
resource, err := rm.DiscoverResource(ctx, id, logger, preventCreation)
1035+
resource, err := rm.DiscoverResource(ctx, id, ids.ApiSource, logger, preventCreation)
10361036
if err != nil {
10371037
logger.Warn("User attempted to create new resource not authorized to create", zap.Any("id", id.String()), zap.Any("user", auth.GetUserFromContext(ctx)), zap.Error(err))
10381038
http.Error(writer, "Not Authorized", http.StatusForbidden)

0 commit comments

Comments
 (0)