From 52f0af0ccc9e5e4e4ddc46df0b047d17d45bc5de Mon Sep 17 00:00:00 2001
From: Denis Kirillov <denis@nspcc.ru>
Date: Fri, 11 Mar 2022 12:59:52 +0300
Subject: [PATCH] [#372] Check parameters before creating container

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
---
 authmate/authmate.go | 27 +++++++++++++--------------
 cmd/authmate/main.go | 36 ++++++++++++++++++++++++++++--------
 2 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/authmate/authmate.go b/authmate/authmate.go
index 105015ad..dfb29898 100644
--- a/authmate/authmate.go
+++ b/authmate/authmate.go
@@ -230,16 +230,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
 		lifetime.Exp = lifetime.Iat + epochLifetime
 	}
 
-	idOwner := owner.NewIDFromPublicKey(&options.NeoFSKey.PrivateKey.PublicKey)
-
-	a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
-		zap.String("friendly_name", options.Container.FriendlyName),
-		zap.String("placement_policy", options.Container.PlacementPolicy))
-	if id, err = a.checkContainer(ctx, options.Container, idOwner); err != nil {
-		return err
-	}
-
-	gatesData, err := createTokens(options, lifetime, id)
+	gatesData, err := createTokens(options, lifetime)
 	if err != nil {
 		return err
 	}
@@ -251,6 +242,15 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
 
 	box.ContainerPolicy = policies
 
+	idOwner := owner.NewIDFromPublicKey(&options.NeoFSKey.PrivateKey.PublicKey)
+
+	a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
+		zap.String("friendly_name", options.Container.FriendlyName),
+		zap.String("placement_policy", options.Container.PlacementPolicy))
+	if id, err = a.checkContainer(ctx, options.Container, idOwner); err != nil {
+		return err
+	}
+
 	a.log.Info("store bearer token into NeoFS",
 		zap.Stringer("owner_tkn", idOwner))
 
@@ -318,7 +318,7 @@ func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSe
 	return enc.Encode(or)
 }
 
-func buildEACLTable(cid *cid.ID, eaclTable []byte) (*eacl.Table, error) {
+func buildEACLTable(eaclTable []byte) (*eacl.Table, error) {
 	table := eacl.NewTable()
 	if len(eaclTable) != 0 {
 		return table, table.UnmarshalJSON(eaclTable)
@@ -332,7 +332,6 @@ func buildEACLTable(cid *cid.ID, eaclTable []byte) (*eacl.Table, error) {
 	// matcher := eacl.MatchStringEqual
 	// record.AddFilter(from eacl.FilterHeaderType, matcher eacl.Match, name string, value string)
 	eacl.AddFormedTarget(record, eacl.RoleOthers)
-	table.SetCID(cid)
 	table.AddRecord(record)
 
 	return table, nil
@@ -437,10 +436,10 @@ func buildSessionTokens(key *keys.PrivateKey, oid *owner.ID, lifetime lifetimeOp
 	return sessionTokens, nil
 }
 
-func createTokens(options *IssueSecretOptions, lifetime lifetimeOptions, cid *cid.ID) ([]*accessbox.GateData, error) {
+func createTokens(options *IssueSecretOptions, lifetime lifetimeOptions) ([]*accessbox.GateData, error) {
 	gates := make([]*accessbox.GateData, len(options.GatesPublicKeys))
 
-	table, err := buildEACLTable(cid, options.EACLRules)
+	table, err := buildEACLTable(options.EACLRules)
 	if err != nil {
 		return nil, fmt.Errorf("failed to build eacl table: %w", err)
 	}
diff --git a/cmd/authmate/main.go b/cmd/authmate/main.go
index 8f32e011..c5592c07 100644
--- a/cmd/authmate/main.go
+++ b/cmd/authmate/main.go
@@ -271,6 +271,16 @@ It will be ceil rounded to the nearest amount of epoch.`,
 				return cli.Exit(fmt.Sprintf("couldn't parse container policy: %s", err.Error()), 6)
 			}
 
+			bearerRules, err := getJSONRules(eaclRulesFlag)
+			if err != nil {
+				return cli.Exit(fmt.Sprintf("couldn't parse 'bearer-rules' flag: %s", err.Error()), 7)
+			}
+
+			sessionRules, err := getSessionRules(sessionTokenFlag)
+			if err != nil {
+				return cli.Exit(fmt.Sprintf("couldn't parse 'session-token' flag: %s", err.Error()), 8)
+			}
+
 			issueSecretOptions := &authmate.IssueSecretOptions{
 				Container: authmate.ContainerOptions{
 					ID:              containerID,
@@ -279,8 +289,8 @@ It will be ceil rounded to the nearest amount of epoch.`,
 				},
 				NeoFSKey:              key,
 				GatesPublicKeys:       gatesPublicKeys,
-				EACLRules:             getJSONRules(eaclRulesFlag),
-				SessionTokenRules:     getSessionRules(sessionTokenFlag),
+				EACLRules:             bearerRules,
+				SessionTokenRules:     sessionRules,
 				ContainerPolicies:     policies,
 				Lifetime:              lifetimeFlag,
 				AwsCliCredentialsFile: awcCliCredFile,
@@ -315,17 +325,27 @@ func parsePolicies(val string) (authmate.ContainerPolicies, error) {
 	return policies, nil
 }
 
-func getJSONRules(val string) []byte {
-	if data, err := os.ReadFile(val); err == nil {
-		return data
+func getJSONRules(val string) ([]byte, error) {
+	if val == "" {
+		return nil, nil
+	}
+	data := []byte(val)
+	if json.Valid(data) {
+		return data, nil
 	}
 
-	return []byte(val)
+	if data, err := os.ReadFile(val); err == nil {
+		if json.Valid(data) {
+			return data, nil
+		}
+	}
+
+	return nil, fmt.Errorf("coudln't read json file or its content is invalid")
 }
 
-func getSessionRules(r string) []byte {
+func getSessionRules(r string) ([]byte, error) {
 	if r == "none" {
-		return nil
+		return nil, nil
 	}
 	return getJSONRules(r)
 }