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