2022-03-28 12:09:49 +03:00
package bearer
2022-03-23 15:47:34 +03:00
import (
2022-06-17 10:36:23 +03:00
"context"
2022-03-23 15:47:34 +03:00
"encoding/json"
"fmt"
2022-08-15 10:29:30 +03:00
"os"
2022-06-17 10:36:23 +03:00
"time"
2022-03-23 15:47:34 +03:00
2023-03-07 16:38:26 +03:00
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
2022-03-23 15:47:34 +03:00
"github.com/spf13/cobra"
)
const (
eaclFlag = "eacl"
issuedAtFlag = "issued-at"
notValidBeforeFlag = "not-valid-before"
ownerFlag = "owner"
outFlag = "out"
2022-06-23 16:52:47 +03:00
jsonFlag = commonflags . JSON
2023-07-14 16:08:01 +03:00
impersonateFlag = "impersonate"
2022-03-23 15:47:34 +03:00
)
var createCmd = & cobra . Command {
Use : "create" ,
Short : "Create bearer token" ,
2022-03-23 16:22:09 +03:00
Long : ` Create bearer token .
All epoch flags can be specified relative to the current epoch with the + n syntax .
2022-05-18 12:22:02 +03:00
In this case -- ` + commonflags.RPC + ` flag should be specified and the epoch in bearer token
2022-03-23 16:22:09 +03:00
is set to current epoch + n .
` ,
2022-07-19 15:53:26 +03:00
Run : createToken ,
2022-03-23 15:47:34 +03:00
}
func init ( ) {
2023-07-14 16:08:01 +03:00
createCmd . Flags ( ) . StringP ( eaclFlag , "e" , "" , "Path to the extended ACL table (mutually exclusive with --impersonate flag)" )
2023-07-14 11:58:13 +03:00
createCmd . Flags ( ) . StringP ( issuedAtFlag , "i" , "+0" , "Epoch to issue token at" )
createCmd . Flags ( ) . StringP ( notValidBeforeFlag , "n" , "+0" , "Not valid before epoch" )
2022-12-21 10:59:35 +03:00
createCmd . Flags ( ) . StringP ( commonflags . ExpireAt , "x" , "" , "The last active epoch for the token" )
2022-10-11 17:02:03 +03:00
createCmd . Flags ( ) . StringP ( ownerFlag , "o" , "" , "Token owner" )
createCmd . Flags ( ) . String ( outFlag , "" , "File to write token to" )
createCmd . Flags ( ) . Bool ( jsonFlag , false , "Output token in JSON" )
2023-07-14 16:08:01 +03:00
createCmd . Flags ( ) . Bool ( impersonateFlag , false , "Mark token as impersonate to consider the token signer as the request owner (mutually exclusive with --eacl flag)" )
2022-05-18 12:22:02 +03:00
createCmd . Flags ( ) . StringP ( commonflags . RPC , commonflags . RPCShorthand , commonflags . RPCDefault , commonflags . RPCUsage )
2022-03-23 15:47:34 +03:00
2023-07-14 16:08:01 +03:00
createCmd . MarkFlagsMutuallyExclusive ( eaclFlag , impersonateFlag )
2022-03-23 15:47:34 +03:00
_ = cobra . MarkFlagFilename ( createCmd . Flags ( ) , eaclFlag )
2022-07-19 15:45:58 +03:00
_ = cobra . MarkFlagRequired ( createCmd . Flags ( ) , commonflags . ExpireAt )
2022-03-23 15:47:34 +03:00
_ = cobra . MarkFlagRequired ( createCmd . Flags ( ) , ownerFlag )
_ = cobra . MarkFlagRequired ( createCmd . Flags ( ) , outFlag )
}
2022-07-19 15:53:26 +03:00
func createToken ( cmd * cobra . Command , _ [ ] string ) {
2022-06-08 13:13:44 +03:00
iat , iatRelative , err := common . ParseEpoch ( cmd , issuedAtFlag )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't parse --" + issuedAtFlag + " flag: %w" , err )
2022-07-19 15:53:26 +03:00
2022-07-19 15:45:58 +03:00
exp , expRelative , err := common . ParseEpoch ( cmd , commonflags . ExpireAt )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't parse --" + commonflags . ExpireAt + " flag: %w" , err )
2022-07-19 15:53:26 +03:00
2022-06-08 13:13:44 +03:00
nvb , nvbRelative , err := common . ParseEpoch ( cmd , notValidBeforeFlag )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't parse --" + notValidBeforeFlag + " flag: %w" , err )
2022-07-19 15:53:26 +03:00
2022-03-23 16:22:09 +03:00
if iatRelative || expRelative || nvbRelative {
2023-07-14 11:58:13 +03:00
endpoint , _ := cmd . Flags ( ) . GetString ( commonflags . RPC )
if len ( endpoint ) == 0 {
commonCmd . ExitOnErr ( cmd , "can't fetch current epoch: %w" , fmt . Errorf ( "'%s' flag value must be specified" , commonflags . RPC ) )
}
2022-06-17 10:36:23 +03:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second * 30 )
defer cancel ( )
2022-12-27 12:36:30 +03:00
currEpoch , err := internalclient . GetCurrentEpoch ( ctx , cmd , endpoint )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't fetch current epoch: %w" , err )
2022-07-19 15:53:26 +03:00
2022-03-23 16:22:09 +03:00
if iatRelative {
iat += currEpoch
}
if expRelative {
exp += currEpoch
}
if nvbRelative {
nvb += currEpoch
}
}
2022-03-23 15:47:34 +03:00
if exp < nvb {
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "" ,
2022-07-19 15:53:26 +03:00
fmt . Errorf ( "expiration epoch is less than not-valid-before epoch: %d < %d" , exp , nvb ) )
2022-03-23 15:47:34 +03:00
}
ownerStr , _ := cmd . Flags ( ) . GetString ( ownerFlag )
2022-05-17 16:59:46 +03:00
var ownerID user . ID
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't parse recipient: %w" , ownerID . DecodeString ( ownerStr ) )
2022-03-23 15:47:34 +03:00
2022-05-12 10:22:02 +03:00
var b bearer . Token
2022-06-03 17:12:55 +03:00
b . SetExp ( exp )
b . SetNbf ( nvb )
b . SetIat ( iat )
b . ForUser ( ownerID )
2022-03-23 15:47:34 +03:00
2023-07-14 16:08:01 +03:00
impersonate , _ := cmd . Flags ( ) . GetBool ( impersonateFlag )
b . SetImpersonate ( impersonate )
2022-03-23 15:47:34 +03:00
eaclPath , _ := cmd . Flags ( ) . GetString ( eaclFlag )
if eaclPath != "" {
table := eaclSDK . NewTable ( )
2022-08-15 10:29:30 +03:00
raw , err := os . ReadFile ( eaclPath )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't read extended ACL file: %w" , err )
commonCmd . ExitOnErr ( cmd , "can't parse extended ACL: %w" , json . Unmarshal ( raw , table ) )
2022-05-12 10:22:02 +03:00
b . SetEACLTable ( * table )
2022-03-23 15:47:34 +03:00
}
var data [ ] byte
toJSON , _ := cmd . Flags ( ) . GetBool ( jsonFlag )
if toJSON {
data , err = json . Marshal ( b )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't mashal token to JSON: %w" , err )
2022-03-23 15:47:34 +03:00
} else {
2022-05-12 10:22:02 +03:00
data = b . Marshal ( )
2022-03-23 15:47:34 +03:00
}
out , _ := cmd . Flags ( ) . GetString ( outFlag )
2023-10-31 14:56:55 +03:00
err = os . WriteFile ( out , data , 0 o644 )
2023-01-16 12:20:16 +03:00
commonCmd . ExitOnErr ( cmd , "can't write token to file: %w" , err )
2022-03-23 15:47:34 +03:00
}