diff --git a/cmd/neofs-node/object.go b/cmd/neofs-node/object.go index 76b4dfa3..906df233 100644 --- a/cmd/neofs-node/object.go +++ b/cmd/neofs-node/object.go @@ -353,6 +353,7 @@ func initObjectService(c *cfg) { eacl.WithMorphClient(c.cfgObject.cnrClient), eacl.WithLogger(c.log), ), + acl.WithNetmapState(c.cfgNetmap.state), ), ), ) diff --git a/pkg/services/object/acl/acl.go b/pkg/services/object/acl/acl.go index b3335400..5ed6f8c2 100644 --- a/pkg/services/object/acl/acl.go +++ b/pkg/services/object/acl/acl.go @@ -15,6 +15,7 @@ import ( v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" crypto "github.com/nspcc-dev/neofs-crypto" core "github.com/nspcc-dev/neofs-node/pkg/core/container" + "github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore" "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl" eaclV2 "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl/v2" @@ -82,6 +83,8 @@ type eACLCfg struct { eACL *eacl.Validator localStorage *localstore.Storage + + state netmap.State } type accessErr struct { @@ -521,7 +524,7 @@ func eACLCheck(msg interface{}, reqInfo requestInfo, cfg *eACLCfg) bool { } // if bearer token is not present, isValidBearer returns true - if !isValidBearer(reqInfo) { + if !isValidBearer(reqInfo, cfg.state) { return false } @@ -606,7 +609,7 @@ func eACLErr(info requestInfo) error { // isValidBearer returns true if bearer token correctly signed by authorized // entity. This method might be define on whole ACL service because it will // require to fetch current epoch to check lifetime. -func isValidBearer(reqInfo requestInfo) bool { +func isValidBearer(reqInfo requestInfo, st netmap.State) bool { token := reqInfo.bearer // 0. Check if bearer token is present in reqInfo. It might be non nil @@ -653,7 +656,19 @@ func isValidBearer(reqInfo requestInfo) bool { } } - // todo: 4. Then check token lifetime. + // 4. Then check token lifetime. + if !isValidLifetime(token.GetBody().GetLifetime(), st.CurrentEpoch()) { + return false + } return true } + +func isValidLifetime(lifetime *bearer.TokenLifetime, epoch uint64) bool { + // The "exp" (expiration time) claim identifies the expiration time on + // or after which the JWT MUST NOT be accepted for processing. + // The "nbf" (not before) claim identifies the time before which the JWT + // MUST NOT be accepted for processing + // RFC 7519 sections 4.1.4, 4.1.5 + return epoch >= lifetime.GetNbf() && epoch <= lifetime.GetExp() +} diff --git a/pkg/services/object/acl/opts.go b/pkg/services/object/acl/opts.go index 4dcb321e..19b9c286 100644 --- a/pkg/services/object/acl/opts.go +++ b/pkg/services/object/acl/opts.go @@ -3,6 +3,7 @@ package acl import ( "github.com/nspcc-dev/neofs-api-go/v2/object" "github.com/nspcc-dev/neofs-node/pkg/core/container" + "github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore" "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl" ) @@ -41,3 +42,10 @@ func WithLocalStorage(v *localstore.Storage) Option { c.localStorage = v } } + +// WithNetmapState returns options to set global netmap state. +func WithNetmapState(v netmap.State) Option { + return func(c *cfg) { + c.state = v + } +}