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) { var targetRole string var useIdentity string var outputFormat string roleAssumeRoleCmd := flag.NewFlagSet("assume-role", flag.ExitOnError) roleAssumeRoleCmd.StringVar(&targetRole, "r", "", "Target role (required)") roleAssumeRoleCmd.StringVar(&targetRole, "rolename", "", "Target role (required)") roleAssumeRoleCmd.StringVar(&useIdentity, "identity", "", "Identity to use (required)") roleAssumeRoleCmd.StringVar(&outputFormat, "output", "json", "Output format (json or text)") roleAssumeRoleCmd.Parse(args) fmt.Println("output format is", outputFormat) if targetRole == "" { fmt.Println("Error: either -r or --rolename 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) } 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) } // If the file exists, it will be deleted if _, err := os.Stat(fmt.Sprintf("%s/%s.json", dir, targetRole)); err == nil { err = os.Remove(fmt.Sprintf("%s/%s.json", dir, targetRole)) if err != nil { fmt.Printf("Error deleting existing role file: %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, "rolename", "", "Target role (required)") roleattachpolicyCmd.StringVar(&useIdentity, "identity", "", "Identity to use (default: default)") roleattachpolicyCmd.Parse(args) if targetRole == "" { fmt.Println("Error: either --rolename 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:]) }