diff --git a/CHANGELOG.md b/CHANGELOG.md
index 96d9e88e..5c12e026 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@
- Container `__NEOFS__LOCK_UNTIL` attribute (#357)
- `CONTAINER_LOCKED` status (#357)
- `CONTAINER_AWAIT_TIMEOUT` status (#358)
+- `SetAttribute` and `RemoveAttribute` RPC to `ContainerService` (#362)
+- `SETATTRIBUTE` and `REMOVEATTRIBUTE` verbs for container sessions V1 (#362)
### Changed
- `ContainerService`'s `Put`, `Delete` and `SetExtendedACL` RPC are async/await now (#358)
diff --git a/container/service.proto b/container/service.proto
index 91056b35..5676d7c0 100644
--- a/container/service.proto
+++ b/container/service.proto
@@ -6,6 +6,7 @@ import "acl/types.proto";
import "container/types.proto";
import "refs/types.proto";
import "session/types.proto";
+import "status/types.proto";
option csharp_namespace = "Neo.FileStorage.API.Container";
option go_package = "github.com/nspcc-dev/neofs-sdk-go/proto/container";
@@ -22,7 +23,7 @@ service ContainerService {
//
// Statuses:
// - **OK** (0, SECTION_SUCCESS): \
- // request to save the container has been sent to FS chain;
+ // container successfully created;;
// - Common failures (SECTION_FAILURE_COMMON);
// - **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
// transaction was sent but not executed within the deadline.
@@ -38,7 +39,7 @@ service ContainerService {
//
// Statuses:
// - **OK** (0, SECTION_SUCCESS): \
- // request to remove the container has been sent to FS chain;
+ // container successfully removed;
// - Common failures (SECTION_FAILURE_COMMON);
// - **CONTAINER_LOCKED** (3074, SECTION_CONTAINER): \
// deleting a locked container is prohibited;
@@ -71,7 +72,7 @@ service ContainerService {
//
// Statuses:
// - **OK** (0, SECTION_SUCCESS): \
- // request to save container eACL has been sent to FS chain;
+ // container eACL successfully set;
// - Common failures (SECTION_FAILURE_COMMON);
// - **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
// transaction was sent but not executed within the deadline.
@@ -100,6 +101,32 @@ service ContainerService {
// DEPRECATED: every storage node must send storage load directly to `container`
// contract.
rpc AnnounceUsedSpace(AnnounceUsedSpaceRequest) returns (AnnounceUsedSpaceResponse);
+
+ // Sends transaction calling contract method to set container attribute, and
+ // waits for the transaction to be executed. Deadline is determined by the
+ // transport protocol (e.g. `grpc-timeout` header). If the deadline is not
+ // set, server waits 15s after submitting the transaction.
+ //
+ // Statuses:
+ // - **OK** (0, SECTION_SUCCESS): \
+ // attribute successfully set;
+ // - Common failures (SECTION_FAILURE_COMMON);
+ // - **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
+ // transaction was sent but not executed within the deadline.
+ rpc SetAttribute(SetAttributeRequest) returns (SetAttributeResponse);
+
+ // Sends transaction calling contract method to remove container attribute,
+ // and waits for the transaction to be executed. Deadline is determined by
+ // the transport protocol (e.g. `grpc-timeout` header). If the deadline is
+ // not set, server waits 15s after submitting the transaction.
+ //
+ // Statuses:
+ // - **OK** (0, SECTION_SUCCESS): \
+ // attribute successfully removed;
+ // - Common failures (SECTION_FAILURE_COMMON);
+ // - **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
+ // transaction was sent but not executed within the deadline.
+ rpc RemoveAttribute(RemoveAttributeRequest) returns (RemoveAttributeResponse);
}
// New NeoFS Container creation request
@@ -436,3 +463,139 @@ message AnnounceUsedSpaceResponse {
// transmission.
neo.fs.v2.session.ResponseVerificationHeader verify_header = 3;
}
+
+// Attribute setting request
+message SetAttributeRequest {
+ // Request payload message.
+ message Body {
+ // Op parameters message.
+ //
+ // If container does not have the `attribute`, it is added. Otherwise, its
+ // value is swapped.
+ //
+ // `attribute` must be one of:
+ // - `CORS`;
+ // - `__NEOFS__LOCK_UNTIL`.
+ //
+ // In general, requirements for `value` are the same as for container
+ // creation. Attribute-specific requirements:
+ // - `__NEOFS__LOCK_UNTIL`: new timestamp must be after the current one if any
+ message Parameters {
+ // Identifier of the container to set attribute for.
+ neo.fs.v2.refs.ContainerID container_id = 1;
+
+ // Attribute to be set.
+ string attribute = 2;
+
+ // New attribute value.
+ string value = 3;
+ }
+
+ // Op parameters.
+ Parameters parameters = 1;
+
+ // N3 witness of stable-marshalled `parameters` field. The
+ // signature must authenticate either container owner or one of subjects in
+ // the `session_token` field if any. Signature according to
+ // `ECDSA_RFC6979_SHA256` scheme is also supported.
+ neo.fs.v2.refs.SignatureRFC6979 signature = 2;
+
+ // Optional session token. The token must be issued by the container owner.
+ // The token must have at least one subject authenticated by `signature`
+ // field. The token must have at least one context with this container and
+ // `CONTAINER_SETATTRIBUTE` verb.
+ neo.fs.v2.session.SessionTokenV2 session_token = 3;
+
+ // Optional session token (V1). It must not be set together with
+ // `session_token` field that is highly recommended to be used instead.
+ // Requirements are the same for both.
+ neo.fs.v2.session.SessionToken session_token_v1 = 4;
+ }
+
+ // Request payload.
+ Body body = 1;
+
+ // Signature of stable-marshalled `body` field.
+ neo.fs.v2.refs.Signature body_signature = 2;
+}
+
+// Attribute setting response
+message SetAttributeResponse {
+ // Request result message.
+ message Body {
+ // Operation execution status.
+ neo.fs.v2.status.Status status = 1;
+ }
+
+ // Request result.
+ Body body = 1;
+
+ // Signature of stable-marshalled `body` field.
+ neo.fs.v2.refs.Signature body_signature = 2;
+}
+
+// Attribute removal request
+message RemoveAttributeRequest {
+ // Request payload message.
+ message Body {
+ // Op parameters message.
+ //
+ // If container does not have the `attribute`, nothing is done and status
+ // `OK` is returned.
+ //
+ // `attribute` must be one of:
+ // - `CORS`;
+ // - `__NEOFS__LOCK_UNTIL`.
+ //
+ // Attribute-specific requirements:
+ // - `__NEOFS__LOCK_UNTIL`: current timestamp must have already passed if any
+ message Parameters {
+ // Identifier of the container to remove attribute from.
+ neo.fs.v2.refs.ContainerID container_id = 1;
+
+ // Attribute to be removed.
+ string attribute = 2;
+ }
+
+ // Op parameters.
+ Parameters parameters = 1;
+
+ // N3 witness of stable-marshalled `parameters` field. The
+ // signature must authenticate either container owner or one of subjects in
+ // the `session_token` field if any. Signature according to
+ // `ECDSA_RFC6979_SHA256` scheme is also supported.
+ neo.fs.v2.refs.SignatureRFC6979 signature = 2;
+
+ // Optional session token. The token must be issued by the container owner.
+ // The token must have at least one subject authenticated by `signature`
+ // field. The token must have at least one context with this container and
+ // `CONTAINER_REMOVEATTRIBUTE` verb.
+ neo.fs.v2.session.SessionTokenV2 session_token = 3;
+
+ // Optional session token (V1). It must not be set together with
+ // `session_token` field that is highly recommended to be used instead.
+ // Requirements are the same for both.
+ neo.fs.v2.session.SessionToken session_token_v1 = 4;
+ }
+
+ // Request payload.
+ Body body = 1;
+
+ // Signature of stable-marshalled `body` field.
+ neo.fs.v2.refs.Signature body_signature = 2;
+}
+
+// Attribute removal response
+message RemoveAttributeResponse {
+ // Request result message.
+ message Body {
+ // Operation execution status.
+ neo.fs.v2.status.Status status = 1;
+ }
+
+ // Request result.
+ Body body = 1;
+
+ // Signature of stable-marshalled `body` field.
+ neo.fs.v2.refs.Signature body_signature = 2;
+}
diff --git a/proto-docs/container.md b/proto-docs/container.md
index f8f994eb..bc515357 100644
--- a/proto-docs/container.md
+++ b/proto-docs/container.md
@@ -33,6 +33,16 @@
- [PutRequest.Body](#neo.fs.v2.container.PutRequest.Body)
- [PutResponse](#neo.fs.v2.container.PutResponse)
- [PutResponse.Body](#neo.fs.v2.container.PutResponse.Body)
+ - [RemoveAttributeRequest](#neo.fs.v2.container.RemoveAttributeRequest)
+ - [RemoveAttributeRequest.Body](#neo.fs.v2.container.RemoveAttributeRequest.Body)
+ - [RemoveAttributeRequest.Body.Parameters](#neo.fs.v2.container.RemoveAttributeRequest.Body.Parameters)
+ - [RemoveAttributeResponse](#neo.fs.v2.container.RemoveAttributeResponse)
+ - [RemoveAttributeResponse.Body](#neo.fs.v2.container.RemoveAttributeResponse.Body)
+ - [SetAttributeRequest](#neo.fs.v2.container.SetAttributeRequest)
+ - [SetAttributeRequest.Body](#neo.fs.v2.container.SetAttributeRequest.Body)
+ - [SetAttributeRequest.Body.Parameters](#neo.fs.v2.container.SetAttributeRequest.Body.Parameters)
+ - [SetAttributeResponse](#neo.fs.v2.container.SetAttributeResponse)
+ - [SetAttributeResponse.Body](#neo.fs.v2.container.SetAttributeResponse.Body)
- [SetExtendedACLRequest](#neo.fs.v2.container.SetExtendedACLRequest)
- [SetExtendedACLRequest.Body](#neo.fs.v2.container.SetExtendedACLRequest.Body)
- [SetExtendedACLResponse](#neo.fs.v2.container.SetExtendedACLResponse)
@@ -74,6 +84,8 @@ rpc List(ListRequest) returns (ListResponse);
rpc SetExtendedACL(SetExtendedACLRequest) returns (SetExtendedACLResponse);
rpc GetExtendedACL(GetExtendedACLRequest) returns (GetExtendedACLResponse);
rpc AnnounceUsedSpace(AnnounceUsedSpaceRequest) returns (AnnounceUsedSpaceResponse);
+rpc SetAttribute(SetAttributeRequest) returns (SetAttributeResponse);
+rpc RemoveAttribute(RemoveAttributeRequest) returns (RemoveAttributeResponse);
```
@@ -86,7 +98,7 @@ set, server waits 15s after submitting the transaction.
Statuses:
- **OK** (0, SECTION_SUCCESS): \
- request to save the container has been sent to FS chain;
+ container successfully created;;
- Common failures (SECTION_FAILURE_COMMON);
- **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
transaction was sent but not executed within the deadline.
@@ -106,7 +118,7 @@ object would be also removed).
Statuses:
- **OK** (0, SECTION_SUCCESS): \
- request to remove the container has been sent to FS chain;
+ container successfully removed;
- Common failures (SECTION_FAILURE_COMMON);
- **CONTAINER_LOCKED** (3074, SECTION_CONTAINER): \
deleting a locked container is prohibited;
@@ -151,7 +163,7 @@ not set, server waits 15s after submitting the transaction.
Statuses:
- **OK** (0, SECTION_SUCCESS): \
- request to save container eACL has been sent to FS chain;
+ container eACL successfully set;
- Common failures (SECTION_FAILURE_COMMON);
- **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
transaction was sent but not executed within the deadline.
@@ -191,6 +203,40 @@ contract.
| Name | Input | Output |
| ---- | ----- | ------ |
| AnnounceUsedSpace | [AnnounceUsedSpaceRequest](#neo.fs.v2.container.AnnounceUsedSpaceRequest) | [AnnounceUsedSpaceResponse](#neo.fs.v2.container.AnnounceUsedSpaceResponse) |
+#### Method SetAttribute
+
+Sends transaction calling contract method to set container attribute, and
+waits for the transaction to be executed. Deadline is determined by the
+transport protocol (e.g. `grpc-timeout` header). If the deadline is not
+set, server waits 15s after submitting the transaction.
+
+Statuses:
+- **OK** (0, SECTION_SUCCESS): \
+ attribute successfully set;
+- Common failures (SECTION_FAILURE_COMMON);
+- **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
+ transaction was sent but not executed within the deadline.
+
+| Name | Input | Output |
+| ---- | ----- | ------ |
+| SetAttribute | [SetAttributeRequest](#neo.fs.v2.container.SetAttributeRequest) | [SetAttributeResponse](#neo.fs.v2.container.SetAttributeResponse) |
+#### Method RemoveAttribute
+
+Sends transaction calling contract method to remove container attribute,
+and waits for the transaction to be executed. Deadline is determined by
+the transport protocol (e.g. `grpc-timeout` header). If the deadline is
+not set, server waits 15s after submitting the transaction.
+
+Statuses:
+- **OK** (0, SECTION_SUCCESS): \
+ attribute successfully removed;
+- Common failures (SECTION_FAILURE_COMMON);
+- **CONTAINER_AWAIT_TIMEOUT** (3075, SECTION_CONTAINER): \
+ transaction was sent but not executed within the deadline.
+
+| Name | Input | Output |
+| ---- | ----- | ------ |
+| RemoveAttribute | [RemoveAttributeRequest](#neo.fs.v2.container.RemoveAttributeRequest) | [RemoveAttributeResponse](#neo.fs.v2.container.RemoveAttributeResponse) |
@@ -514,6 +560,150 @@ returned here to make sure everything has been done as expected.
| container_id | [neo.fs.v2.refs.ContainerID](#neo.fs.v2.refs.ContainerID) | | Unique identifier of the newly created container |
+
+
+### Message RemoveAttributeRequest
+Attribute removal request
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| body | [RemoveAttributeRequest.Body](#neo.fs.v2.container.RemoveAttributeRequest.Body) | | Request payload. |
+| body_signature | [neo.fs.v2.refs.Signature](#neo.fs.v2.refs.Signature) | | Signature of stable-marshalled `body` field. |
+
+
+
+
+### Message RemoveAttributeRequest.Body
+Request payload message.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| parameters | [RemoveAttributeRequest.Body.Parameters](#neo.fs.v2.container.RemoveAttributeRequest.Body.Parameters) | | Op parameters. |
+| signature | [neo.fs.v2.refs.SignatureRFC6979](#neo.fs.v2.refs.SignatureRFC6979) | | N3 witness of stable-marshalled `parameters` field. The signature must authenticate either container owner or one of subjects in the `session_token` field if any. Signature according to `ECDSA_RFC6979_SHA256` scheme is also supported. |
+| session_token | [neo.fs.v2.session.SessionTokenV2](#neo.fs.v2.session.SessionTokenV2) | | Optional session token. The token must be issued by the container owner. The token must have at least one subject authenticated by `signature` field. The token must have at least one context with this container and `CONTAINER_REMOVEATTRIBUTE` verb. |
+| session_token_v1 | [neo.fs.v2.session.SessionToken](#neo.fs.v2.session.SessionToken) | | Optional session token (V1). It must not be set together with `session_token` field that is highly recommended to be used instead. Requirements are the same for both. |
+
+
+
+
+### Message RemoveAttributeRequest.Body.Parameters
+Op parameters message.
+
+If container does not have the `attribute`, nothing is done and status
+`OK` is returned.
+
+`attribute` must be one of:
+ - `CORS`;
+ - `__NEOFS__LOCK_UNTIL`.
+
+Attribute-specific requirements:
+ - `__NEOFS__LOCK_UNTIL`: current timestamp must have already passed if any
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| container_id | [neo.fs.v2.refs.ContainerID](#neo.fs.v2.refs.ContainerID) | | Identifier of the container to remove attribute from. |
+| attribute | [string](#string) | | Attribute to be removed. |
+
+
+
+
+### Message RemoveAttributeResponse
+Attribute removal response
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| body | [RemoveAttributeResponse.Body](#neo.fs.v2.container.RemoveAttributeResponse.Body) | | Request result. |
+| body_signature | [neo.fs.v2.refs.Signature](#neo.fs.v2.refs.Signature) | | Signature of stable-marshalled `body` field. |
+
+
+
+
+### Message RemoveAttributeResponse.Body
+Request result message.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| status | [neo.fs.v2.status.Status](#neo.fs.v2.status.Status) | | Operation execution status. |
+
+
+
+
+### Message SetAttributeRequest
+Attribute setting request
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| body | [SetAttributeRequest.Body](#neo.fs.v2.container.SetAttributeRequest.Body) | | Request payload. |
+| body_signature | [neo.fs.v2.refs.Signature](#neo.fs.v2.refs.Signature) | | Signature of stable-marshalled `body` field. |
+
+
+
+
+### Message SetAttributeRequest.Body
+Request payload message.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| parameters | [SetAttributeRequest.Body.Parameters](#neo.fs.v2.container.SetAttributeRequest.Body.Parameters) | | Op parameters. |
+| signature | [neo.fs.v2.refs.SignatureRFC6979](#neo.fs.v2.refs.SignatureRFC6979) | | N3 witness of stable-marshalled `parameters` field. The signature must authenticate either container owner or one of subjects in the `session_token` field if any. Signature according to `ECDSA_RFC6979_SHA256` scheme is also supported. |
+| session_token | [neo.fs.v2.session.SessionTokenV2](#neo.fs.v2.session.SessionTokenV2) | | Optional session token. The token must be issued by the container owner. The token must have at least one subject authenticated by `signature` field. The token must have at least one context with this container and `CONTAINER_SETATTRIBUTE` verb. |
+| session_token_v1 | [neo.fs.v2.session.SessionToken](#neo.fs.v2.session.SessionToken) | | Optional session token (V1). It must not be set together with `session_token` field that is highly recommended to be used instead. Requirements are the same for both. |
+
+
+
+
+### Message SetAttributeRequest.Body.Parameters
+Op parameters message.
+
+If container does not have the `attribute`, it is added. Otherwise, its
+value is swapped.
+
+`attribute` must be one of:
+ - `CORS`;
+ - `__NEOFS__LOCK_UNTIL`.
+
+In general, requirements for `value` are the same as for container
+creation. Attribute-specific requirements:
+ - `__NEOFS__LOCK_UNTIL`: new timestamp must be after the current one if any
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| container_id | [neo.fs.v2.refs.ContainerID](#neo.fs.v2.refs.ContainerID) | | Identifier of the container to set attribute for. |
+| attribute | [string](#string) | | Attribute to be set. |
+| value | [string](#string) | | New attribute value. |
+
+
+
+
+### Message SetAttributeResponse
+Attribute setting response
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| body | [SetAttributeResponse.Body](#neo.fs.v2.container.SetAttributeResponse.Body) | | Request result. |
+| body_signature | [neo.fs.v2.refs.Signature](#neo.fs.v2.refs.Signature) | | Signature of stable-marshalled `body` field. |
+
+
+
+
+### Message SetAttributeResponse.Body
+Request result message.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| status | [neo.fs.v2.status.Status](#neo.fs.v2.status.Status) | | Operation execution status. |
+
+
### Message SetExtendedACLRequest
diff --git a/proto-docs/session.md b/proto-docs/session.md
index 5e3a88df..70ed0fa7 100644
--- a/proto-docs/session.md
+++ b/proto-docs/session.md
@@ -250,7 +250,7 @@ SessionContextV2 carries unified context for both ObjectService and ContainerSer
| ----- | ---- | ----- | ----------- |
| container | [neo.fs.v2.refs.ContainerID](#neo.fs.v2.refs.ContainerID) | | Container where operation is allowed. For container operations, this is the container being operated on. For object operations, this is the container holding the objects. |
| objects | [neo.fs.v2.refs.ObjectID](#neo.fs.v2.refs.ObjectID) | repeated | Specific objects where operation is allowed. Only relevant for object operations. Empty list means all objects in the container. Maximum number of objects: 1000. |
-| verbs | [Verb](#neo.fs.v2.session.Verb) | repeated | Operations authorized for this context. Maximum number of verbs: 10. |
+| verbs | [Verb](#neo.fs.v2.session.Verb) | repeated | Operations authorized for this context. Maximum number of verbs: 12. |
@@ -393,6 +393,8 @@ Container request verbs
| PUT | 1 | Refers to container.Put RPC call |
| DELETE | 2 | Refers to container.Delete RPC call |
| SETEACL | 3 | Refers to container.SetExtendedACL RPC call |
+| SETATTRIBUTE | 4 | Refers to container.SetAttribute RPC call |
+| REMOVEATTRIBUTE | 5 | Refers to container.RemoveAttribute RPC call |
@@ -434,6 +436,8 @@ container service operations.
| CONTAINER_PUT | 8 | Refers to container.Put RPC call |
| CONTAINER_DELETE | 9 | Refers to container.Delete RPC call |
| CONTAINER_SETEACL | 10 | Refers to container.SetExtendedACL RPC call |
+| CONTAINER_SETATTRIBUTE | 11 | Refers to container.SetAttribute RPC call |
+| CONTAINER_REMOVEATTRIBUTE | 12 | Refers to container.RemoveAttribute RPC call |
diff --git a/session/types.proto b/session/types.proto
index b1a69a91..18fe03cc 100644
--- a/session/types.proto
+++ b/session/types.proto
@@ -49,6 +49,12 @@ enum Verb {
// Refers to container.SetExtendedACL RPC call
CONTAINER_SETEACL = 10;
+
+ // Refers to container.SetAttribute RPC call
+ CONTAINER_SETATTRIBUTE = 11;
+
+ // Refers to container.RemoveAttribute RPC call
+ CONTAINER_REMOVEATTRIBUTE = 12;
}
// Context information for Session Tokens related to ObjectService requests
@@ -114,6 +120,12 @@ message ContainerSessionContext {
// Refers to container.SetExtendedACL RPC call
SETEACL = 3;
+
+ // Refers to container.SetAttribute RPC call
+ SETATTRIBUTE = 4;
+
+ // Refers to container.RemoveAttribute RPC call
+ REMOVEATTRIBUTE = 5;
}
// Type of request for which the token is issued
Verb verb = 1 [json_name = "verb"];
@@ -325,7 +337,7 @@ message SessionContextV2 {
repeated neo.fs.v2.refs.ObjectID objects = 2 [json_name = "objects"];
// Operations authorized for this context.
- // Maximum number of verbs: 10.
+ // Maximum number of verbs: 12.
repeated Verb verbs = 3 [json_name = "verbs"];
}