Working through authentication, role and policy basics
This commit is contained in:
@@ -5,25 +5,13 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"libshared"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
func authMain(args []string) {
|
|
||||||
authCmd := flag.NewFlagSet("auth", flag.ExitOnError)
|
|
||||||
token := authCmd.String("t", "", "Auth token")
|
|
||||||
verbose := authCmd.Bool("v", false, "Verbose output")
|
|
||||||
|
|
||||||
authCmd.Parse(args)
|
|
||||||
|
|
||||||
fmt.Println("Auth command")
|
|
||||||
fmt.Println("Token:", *token)
|
|
||||||
fmt.Println("Verbose:", *verbose)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
var authCmd *flag.FlagSet
|
var authCmd *flag.FlagSet
|
||||||
|
|
||||||
type AuthenticateRequest struct {
|
type AuthenticateRequest struct {
|
||||||
@@ -32,53 +20,34 @@ type AuthenticateRequest struct {
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AuthenticateResponse struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
func authLocalGetToken() {
|
func authLocalGetToken() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func authLocalAuthenticate(args []string) {
|
func authLocalAuthenticate(args []string) {
|
||||||
|
|
||||||
var authSource string
|
|
||||||
var authUsername string
|
var authUsername string
|
||||||
var authPassword string
|
var authPassword string
|
||||||
var authAccountid string
|
var authAccountid string
|
||||||
var outputFormat string
|
var outputFormat string
|
||||||
|
var saveProfile string
|
||||||
|
|
||||||
authCmd.StringVar(&authSource, "s", "", "Source (required)")
|
authCmd.StringVar(&saveProfile, "save-profile", "", "Save authentication profile with given name")
|
||||||
authCmd.StringVar(&authSource, "source", "", "Source (required)")
|
|
||||||
authCmd.StringVar(&authUsername, "u", "", "Username (required)")
|
authCmd.StringVar(&authUsername, "u", "", "Username (required)")
|
||||||
authCmd.StringVar(&authUsername, "username", "", "Username (required)")
|
authCmd.StringVar(&authUsername, "username", "", "Username (required)")
|
||||||
authCmd.StringVar(&authPassword, "p", "", "Password (required)")
|
authCmd.StringVar(&authPassword, "p", "", "Password (required)")
|
||||||
authCmd.StringVar(&authPassword, "password", "", "Password (required)")
|
authCmd.StringVar(&authPassword, "password", "", "Password (required)")
|
||||||
authCmd.StringVar(&authAccountid, "a", "", "Account ID (required)")
|
authCmd.StringVar(&authAccountid, "a", "", "Account ID (required)")
|
||||||
authCmd.StringVar(&authAccountid, "account", "", "Account ID (required)")
|
authCmd.StringVar(&authAccountid, "account", "", "Account ID (required)")
|
||||||
authCmd.StringVar(&outputFormat, "o", "text", "Output format (text or json)")
|
authCmd.StringVar(&outputFormat, "o", "json", "Output format (text or json)")
|
||||||
|
|
||||||
// verbose := authCmd.Bool("v", false, "Verbose output")
|
outputFormat = "json"
|
||||||
|
|
||||||
outputFormat = "text"
|
|
||||||
|
|
||||||
authCmd.Parse(args)
|
authCmd.Parse(args)
|
||||||
|
|
||||||
if authSource == "" {
|
|
||||||
fmt.Println("Error: either -s or --source is required")
|
|
||||||
//authCmd.Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce required flag
|
|
||||||
if authSource == "" {
|
|
||||||
fmt.Println("Error: either -s or --source is required")
|
|
||||||
//authCmd.Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if authSource != "local" {
|
|
||||||
fmt.Println("Error: invalid source. Allowed values: local")
|
|
||||||
//authCmd.Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if authAccountid == "" {
|
if authAccountid == "" {
|
||||||
fmt.Print("Account ID: ")
|
fmt.Print("Account ID: ")
|
||||||
fmt.Scanln(&authAccountid)
|
fmt.Scanln(&authAccountid)
|
||||||
@@ -91,6 +60,11 @@ func authLocalAuthenticate(args []string) {
|
|||||||
if authPassword == "" {
|
if authPassword == "" {
|
||||||
fmt.Print("Password: ")
|
fmt.Print("Password: ")
|
||||||
fmt.Scanln(&authPassword)
|
fmt.Scanln(&authPassword)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputFormat != "json") && (outputFormat != "text") && (outputFormat != "silent") {
|
||||||
|
log.Fatal("Invalid output format. Use 'json', 'text', or 'silent'.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var authenticaterequest AuthenticateRequest
|
var authenticaterequest AuthenticateRequest
|
||||||
@@ -125,30 +99,58 @@ func authLocalAuthenticate(args []string) {
|
|||||||
log.Fatal("Authentication failed with status:", resp.Status)
|
log.Fatal("Authentication failed with status:", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result map[string]interface{}
|
apiresponse := libshared.APIResponse[AuthenticateResponse]{}
|
||||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
||||||
|
// var result map[string]interface{}
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&apiresponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error decoding response:", err)
|
log.Fatal("Error decoding response:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if outputFormat == "json" {
|
if saveProfile != "" {
|
||||||
jsonOutput, err := json.MarshalIndent(result, "", " ")
|
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := filepath.Dir(home + "/.pcloud/identities/" + saveProfile + ".json")
|
||||||
|
err = os.MkdirAll(dir, 0700)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error creating directory:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
profileData, err := json.MarshalIndent(apiresponse.Content, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error encoding profile JSON:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Remove(home + "/.pcloud/identities/" + saveProfile + ".json")
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
log.Fatal("Error removing profile:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(home+"/.pcloud/identities/"+saveProfile+".json", profileData, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error saving profile:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch outputFormat {
|
||||||
|
case "json":
|
||||||
|
jsonOutput, err := json.MarshalIndent(apiresponse.Content, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error encoding JSON output:", err)
|
log.Fatal("Error encoding JSON output:", err)
|
||||||
}
|
}
|
||||||
fmt.Println(string(jsonOutput))
|
fmt.Println(string(jsonOutput))
|
||||||
return
|
case "text":
|
||||||
} else {
|
fmt.Printf("Status: %s\nMessage: %s\n", apiresponse.Status, apiresponse.Message)
|
||||||
for key, value := range result {
|
case "silent":
|
||||||
fmt.Printf("%s: %v\n", key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func authenticateMain(args []string) {
|
func authenticateMain(args []string) {
|
||||||
authCmd = flag.NewFlagSet("auth", flag.ExitOnError)
|
authCmd = flag.NewFlagSet("auth", flag.ExitOnError)
|
||||||
|
|
||||||
authLocalAuthenticate(args)
|
authLocalAuthenticate(args)
|
||||||
//fmt.Println("Verbose:", *verbose)
|
|
||||||
}
|
}
|
||||||
4
go.mod
4
go.mod
@@ -1,3 +1,7 @@
|
|||||||
module upc
|
module upc
|
||||||
|
|
||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
|
require golang.org/x/term v0.41.0
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.42.0 // indirect
|
||||||
|
|||||||
4
go.sum
Normal file
4
go.sum
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
|
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
||||||
|
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
||||||
21
main.go
21
main.go
@@ -16,17 +16,20 @@ type Command struct {
|
|||||||
|
|
||||||
var commands = []Command{
|
var commands = []Command{
|
||||||
{
|
{
|
||||||
Names: []string{"login", "l"},
|
Names: []string{"role"},
|
||||||
Description: "Log into the system",
|
Description: "Role Management",
|
||||||
Handler: func(args []string) {
|
Handler: roleMain,
|
||||||
fmt.Println("Executing login with args:", args)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Names: []string{"auth", "authenticate"},
|
Names: []string{"auth", "authorization"},
|
||||||
Description: "Authenticate with a token",
|
Description: "Role Management",
|
||||||
Handler: authenticateMain,
|
Handler: authenticateMain,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"policy"},
|
||||||
|
Description: "Policy Management",
|
||||||
|
Handler: policyMain,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func printMainUsage() {
|
func printMainUsage() {
|
||||||
@@ -43,7 +46,7 @@ func formatNames(names []string) string {
|
|||||||
return strings.Join(names, ", ")
|
return strings.Join(names, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func findCommand(name string) *Command {
|
func findCommand(name string, commands []Command) *Command {
|
||||||
for _, cmd := range commands {
|
for _, cmd := range commands {
|
||||||
for _, n := range cmd.Names {
|
for _, n := range cmd.Names {
|
||||||
if n == name {
|
if n == name {
|
||||||
@@ -64,7 +67,7 @@ func main() {
|
|||||||
|
|
||||||
subcommand := os.Args[1]
|
subcommand := os.Args[1]
|
||||||
|
|
||||||
cmd := findCommand(subcommand)
|
cmd := findCommand(subcommand, commands)
|
||||||
if cmd == nil {
|
if cmd == nil {
|
||||||
fmt.Println("Error: unknown command:", subcommand)
|
fmt.Println("Error: unknown command:", subcommand)
|
||||||
printMainUsage()
|
printMainUsage()
|
||||||
|
|||||||
204
policy.go
Normal file
204
policy.go
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var policyCmd *flag.FlagSet
|
||||||
|
|
||||||
|
var policyCommands = []Command{
|
||||||
|
{
|
||||||
|
Names: []string{"create-policy"},
|
||||||
|
Description: "Create Policy",
|
||||||
|
Handler: policyCreate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"list-policies"},
|
||||||
|
Description: "List Policies",
|
||||||
|
Handler: policyCreate,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Condition represents each item in the "conditions" array
|
||||||
|
type Condition struct {
|
||||||
|
StatementID string `json:"statementid"`
|
||||||
|
Principal []string `json:"principals"`
|
||||||
|
Actions []string `json:"actions"`
|
||||||
|
Source []string `json:"source"`
|
||||||
|
Effect string `json:"effect"`
|
||||||
|
Operator string `json:"operator"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Policy struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Conditions []Condition `json:"conditions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreatePolicyRequest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
PolicyDocument Policy `json:"PolicyDocument"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreatePolicyResponse struct {
|
||||||
|
PolicyID string `json:"policy_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProfileToken struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IdentityToken struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func policyCreate(args []string) {
|
||||||
|
policyCmd := flag.NewFlagSet("create-policy", flag.ExitOnError)
|
||||||
|
|
||||||
|
var policyname string
|
||||||
|
var useprofile string
|
||||||
|
var policyjson string
|
||||||
|
var policyfile string
|
||||||
|
var policyDescription string
|
||||||
|
var createpolicyrequest CreatePolicyRequest
|
||||||
|
|
||||||
|
var normalizedDocument string
|
||||||
|
|
||||||
|
policyCmd.StringVar(&policyname, "name", "", "Policy Name (required)")
|
||||||
|
policyCmd.StringVar(&policyDescription, "description", "", "Policy Description")
|
||||||
|
policyCmd.StringVar(&useprofile, "profile", "", "Profile")
|
||||||
|
policyCmd.StringVar(&policyjson, "policy-json", "", "Policy JSON")
|
||||||
|
policyCmd.StringVar(&policyfile, "policy-file", "", "JSON Policy File")
|
||||||
|
|
||||||
|
policyCmd.Parse(args)
|
||||||
|
|
||||||
|
if policyname == "" {
|
||||||
|
fmt.Println("Error: either -n or --name is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if useprofile == "" {
|
||||||
|
fmt.Println("Error: either -profile or --profile is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policyjson == "" && policyfile == "" {
|
||||||
|
fmt.Println("Error: either -p/--policy-json or -f/--policy-file is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policyjson != "" && policyfile != "" {
|
||||||
|
fmt.Println("Error: only one of -p/--policy-json or -f/--policy-file can be provided")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Profile file
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
profileData, err := os.ReadFile(home + "/.pcloud/profiles/" + useprofile + ".json")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error opening profile file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Length is", len(profileData))
|
||||||
|
|
||||||
|
if len(profileData) == 0 {
|
||||||
|
fmt.Printf("Profile file is empty: %s\n", home+"/.pcloud/profiles/"+useprofile+".json")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var profileToken ProfileToken
|
||||||
|
err = json.Unmarshal(profileData, &profileToken)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading profile file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Profile Token: ", profileToken.Token)
|
||||||
|
|
||||||
|
if policyfile != "" {
|
||||||
|
content, err := os.ReadFile(policyfile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading policy file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
normalizedDocument = string(content)
|
||||||
|
} else if policyjson != "" {
|
||||||
|
normalizedDocument = policyjson
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate JSON
|
||||||
|
if !json.Valid([]byte(normalizedDocument)) {
|
||||||
|
fmt.Println("Error: invalid JSON for policy document")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
createpolicyrequest.Name = policyname
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(normalizedDocument), &createpolicyrequest.PolicyDocument)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading policy document: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
policyrequestData, err := json.Marshal(createpolicyrequest)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error encoding policy request: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Policy Name:", createpolicyrequest.Name)
|
||||||
|
fmt.Println("Policy JSON:", createpolicyrequest.PolicyDocument)
|
||||||
|
|
||||||
|
apiendpoint := endpoint + "/policy/create-policy"
|
||||||
|
fmt.Println(apiendpoint)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", apiendpoint, bytes.NewBuffer(policyrequestData))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", "Bearer "+profileToken.Token)
|
||||||
|
fmt.Println("Using token:", profileToken.Token)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
fmt.Println("Response status:", resp.Status, resp.Body)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func policyList(args []string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func policyMain(args []string) {
|
||||||
|
fmt.Println("Policy Main")
|
||||||
|
if len(args) < 1 {
|
||||||
|
fmt.Println("Error: subcommand is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
subcommand := args[0]
|
||||||
|
|
||||||
|
cmd := findCommand(subcommand, policyCommands)
|
||||||
|
if cmd == nil {
|
||||||
|
fmt.Println("Error: unknown command:", subcommand)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
cmd.Handler(args[1:])
|
||||||
|
|
||||||
|
}
|
||||||
5
request.go
Normal file
5
request.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func getReq() {
|
||||||
|
|
||||||
|
}
|
||||||
232
role.go
Normal file
232
role.go
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"libshared"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AssumeRoleRequest struct {
|
||||||
|
Rolename string `json:"rolename"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssumeRoleResponse struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var roleattachpolicyCmd *flag.FlagSet
|
||||||
|
|
||||||
|
var roleCommands = []Command{
|
||||||
|
{
|
||||||
|
Names: []string{"attach-policy"},
|
||||||
|
Description: "Role Management",
|
||||||
|
Handler: roleAttachPolicy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"detach-policy"},
|
||||||
|
Description: "Role Management",
|
||||||
|
Handler: roleDetachPolicy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"assume-role"},
|
||||||
|
Description: "Role Management",
|
||||||
|
Handler: assumeRole,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func assumeRole(args []string) {
|
||||||
|
fmt.Println("I assume something")
|
||||||
|
|
||||||
|
var targetRole string
|
||||||
|
var useIdentity string
|
||||||
|
roleAssumeRoleCmd := flag.NewFlagSet("assume-role", flag.ExitOnError)
|
||||||
|
roleAssumeRoleCmd.StringVar(&targetRole, "r", "", "Target role (required)")
|
||||||
|
roleAssumeRoleCmd.StringVar(&targetRole, "role", "", "Target role (required)")
|
||||||
|
roleAssumeRoleCmd.StringVar(&useIdentity, "identity", "", "Identity to use (required)")
|
||||||
|
|
||||||
|
roleAssumeRoleCmd.Parse(args)
|
||||||
|
|
||||||
|
if targetRole == "" {
|
||||||
|
fmt.Println("Error: either -r or --role is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if useIdentity == "" {
|
||||||
|
fmt.Println("Error: either --identity is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
identityData, err := os.ReadFile("/home/farhan/.pcloud/identities/" + useIdentity + ".json")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error opening identity file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var identityToken IdentityToken
|
||||||
|
err = json.Unmarshal(identityData, &identityToken)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading identity file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiendpoint := endpoint + "/role/assume-role"
|
||||||
|
|
||||||
|
var assumerolerequest AssumeRoleRequest
|
||||||
|
assumerolerequest.Rolename = targetRole
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(assumerolerequest)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error marshaling JSON:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", apiendpoint, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", "Bearer "+identityToken.Token)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// var assumeRoleResponse AssumeRoleResponse
|
||||||
|
|
||||||
|
apiresponse := libshared.APIResponse[AssumeRoleResponse]{}
|
||||||
|
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&apiresponse); err != nil {
|
||||||
|
fmt.Printf("Error reading response: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Println("Response status:", resp.Status)
|
||||||
|
fmt.Println("Assumed role token:", apiresponse.Content.Token)
|
||||||
|
|
||||||
|
// fmt.Printf("Attaching policy '%s' to role '%s'\n", , targetRole)
|
||||||
|
|
||||||
|
fmt.Println("Response status:", resp.Status)
|
||||||
|
fmt.Printf("Assuming role '%s'\n", targetRole)
|
||||||
|
fmt.Println("Using identity", resp.Body)
|
||||||
|
|
||||||
|
// Write apiresponse.Content to ~/.pcloud/roles/assumed-<rolename>.json
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := fmt.Sprintf("%s/.pcloud/roles", home)
|
||||||
|
err = os.MkdirAll(dir, 0700)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error creating directory: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
roleData, err := json.MarshalIndent(apiresponse.Content, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error marshaling role data: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
roleFile := fmt.Sprintf("%s/%s.json", dir, targetRole)
|
||||||
|
err = os.WriteFile(roleFile, roleData, 0600)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error writing role file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Assumed role token saved to %s\n", roleFile)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func roleAttachPolicy(args []string) {
|
||||||
|
roleattachpolicyCmd := flag.NewFlagSet("attach-policy", flag.ExitOnError)
|
||||||
|
|
||||||
|
//var policyToAttach string
|
||||||
|
var targetRole string
|
||||||
|
var useIdentity string
|
||||||
|
|
||||||
|
roleattachpolicyCmd.StringVar(&targetRole, "role", "", "Target role (required)")
|
||||||
|
roleattachpolicyCmd.StringVar(&useIdentity, "identity", "", "Identity to use (default: default)")
|
||||||
|
|
||||||
|
roleattachpolicyCmd.Parse(args)
|
||||||
|
|
||||||
|
if targetRole == "" {
|
||||||
|
fmt.Println("Error: either --role is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if useIdentity == "" {
|
||||||
|
fmt.Println("Error: either --identity is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Profile file
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
profileData, err := os.ReadFile(home + "/.pcloud/identities/" + useIdentity + ".json")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error opening profile file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Println("Length is", len(profileData))
|
||||||
|
|
||||||
|
if len(profileData) == 0 {
|
||||||
|
fmt.Printf("Profile file is empty: %s\n", home+"/.pcloud/identities/"+useIdentity+".json")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var profileToken ProfileToken
|
||||||
|
err = json.Unmarshal(profileData, &profileToken)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading profile file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Profile Token: ", profileToken.Token)
|
||||||
|
|
||||||
|
apiendpoint := endpoint + "/role/attach-policy"
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", apiendpoint, nil) //, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", "Bearer YOUR_TOKEN_HERE")
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func roleDetachPolicy(args []string) {
|
||||||
|
fmt.Println("I detach something")
|
||||||
|
}
|
||||||
|
|
||||||
|
func roleMain(args []string) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
fmt.Println("Error: subcommand is required")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
subcommand := args[0]
|
||||||
|
|
||||||
|
cmd := findCommand(subcommand, roleCommands)
|
||||||
|
if cmd == nil {
|
||||||
|
fmt.Println("Error: unknown command:", subcommand)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Handler(args[1:])
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user