mirror of
https://github.com/passbolt/go-passbolt-cli.git
synced 2025-05-12 10:58:21 +00:00
Compare commits
4 commits
e816469304
...
9af92a9a6a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9af92a9a6a | ||
d9703ff6fd | |||
![]() |
9b2d47fecd | ||
![]() |
6070bf3cf4 |
3 changed files with 136 additions and 20 deletions
40
README.md
40
README.md
|
@ -1,10 +1,10 @@
|
||||||
# go-passbolt-cli
|
# go-passbolt-cli
|
||||||
A CLI tool to interact with Passbolt, an Open source Password Manager for teams.
|
A CLI tool to interact with Passbolt, an Open source Password Manager for teams.
|
||||||
|
|
||||||
If you want to do something more complicated: [this Go Module](https://github.com/passbolt/go-passbolt) to Interact with Passbolt from Go might intrest you.
|
If you want to do something more complicated: [this Go Module](https://github.com/passbolt/go-passbolt) to Interact with Passbolt from Go might interest you.
|
||||||
|
|
||||||
|
|
||||||
Disclaimer: This project is community driven and not associated with Passbolt SA
|
Disclaimer: This project is community-driven and not associated with Passbolt SA
|
||||||
# Install
|
# Install
|
||||||
|
|
||||||
## Via Repository (Prefered):
|
## Via Repository (Prefered):
|
||||||
|
@ -28,7 +28,7 @@ Note: tab completion and manpages will need to be installed manually.
|
||||||
Note: this will install the binary as go-passbolt-cli, also tab completion and manpages will be missing.
|
Note: this will install the binary as go-passbolt-cli, also tab completion and manpages will be missing.
|
||||||
|
|
||||||
# Getting Started
|
# Getting Started
|
||||||
First you need to Setup basic information: the Server Address, your Private Key and your Password.
|
First, you need to set up basic information: the Server Address, your Private Key, and your Password.
|
||||||
You have these options:
|
You have these options:
|
||||||
- Save it in the config file using
|
- Save it in the config file using
|
||||||
```
|
```
|
||||||
|
@ -43,23 +43,23 @@ passbolt configure --serverAddress https://passbolt.example.org --userPassword '
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- You can set the Private Key using the flags `--userPrivateKey` or `--userPrivateKeyFile` where `--userPrivateKey` takes the actual private key and `--userPrivateKeyFile` loads the content of a file as the PrivateKey, `--userPrivateKeyFile` overwrites the value of `--userPrivateKey`.
|
- You can set the Private Key using the flags `--userPrivateKey` or `--userPrivateKeyFile` where `--userPrivateKey` takes the actual private key and `--userPrivateKeyFile` loads the content of a file as the PrivateKey, `--userPrivateKeyFile` overwrites the value of `--userPrivateKey`.
|
||||||
- You can also just store the serverAddress and your Private Key, if your Password is not set it will prompt you for it every time.
|
- You can also just store the serverAddress and your Private Key, if your Password is not set, it will prompt you for it every time.
|
||||||
- Passwordless PrivateKeys are unsupported
|
- Passwordless PrivateKeys are unsupported
|
||||||
- MFA settings can also be save permanently this ways
|
- MFA settings can also be saved permanently these ways
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
Generally the Structure of Commands is like this:
|
Generally, the Structure of Commands is like this:
|
||||||
```bash
|
```bash
|
||||||
passbolt action entity [arguments]
|
passbolt action entity [arguments]
|
||||||
```
|
```
|
||||||
|
|
||||||
Action is the Action you want to perform like Creating, Updating or Deleting an Entity.
|
Action is the Action you want to perform, like Creating, Updating, or Deleting an Entity.
|
||||||
Entity is a Resource(Password), Folder, User or Group that you want to apply an action to.
|
Entity is a Resource(Password), Folder, User or Group that you want to apply an action to.
|
||||||
|
|
||||||
In Passbolt a Password is usually revert to as a Resource.
|
In Passbolt, a Password is usually referred to as a Resource.
|
||||||
|
|
||||||
To Create a Resource you can do this, it will return the ID of the newly created Resource:
|
To Create a Resource, you can do this. It will return the ID of the newly created Resource:
|
||||||
```bash
|
```bash
|
||||||
passbolt create resource --name "Test Resource" --password "Strong Password"
|
passbolt create resource --name "Test Resource" --password "Strong Password"
|
||||||
```
|
```
|
||||||
|
@ -68,10 +68,10 @@ You can then list all users:
|
||||||
```bash
|
```bash
|
||||||
passbolt list user
|
passbolt list user
|
||||||
```
|
```
|
||||||
Note: you can adjust which columns should be listed using the flag `--column` or its short from `-c`, if you want multiple column then you need to specify this flag multiple times.
|
Note: you can adjust which columns should be listed using the flag `--column` or its short from `-c`, if you want multiple columns then you need to specify this flag multiple times.
|
||||||
|
|
||||||
|
|
||||||
For sharing we will need to know how we want to share, for that there are these Permission Types:
|
For sharing, we will need to know how we want to share. For that, there are these Permission Types:
|
||||||
|
|
||||||
| Code | Meaning |
|
| Code | Meaning |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
@ -80,32 +80,32 @@ For sharing we will need to know how we want to share, for that there are these
|
||||||
| `15` | "Owner" |
|
| `15` | "Owner" |
|
||||||
| `-1` | Delete existing permission |
|
| `-1` | Delete existing permission |
|
||||||
|
|
||||||
Now that we have a Resource ID, know the ID's of other Users and about know about Permission Types, we can share the Resource with them:
|
Now that we have a Resource ID, know the ID's of other Users and know about Permission Types, we can share the Resource with them:
|
||||||
```bash
|
```bash
|
||||||
passbolt share resource --id id_of_resource_to_share --type type_of_permission --user id_of_user_to_share_with
|
passbolt share resource --id id_of_resource_to_share --type type_of_permission --user id_of_user_to_share_with
|
||||||
```
|
```
|
||||||
Note: you can supply the the users argument multiple times to share with multiple users
|
Note: you can supply the `user` argument multiple times to share with multiple users
|
||||||
|
|
||||||
For sharing with groups the `--group` argument exists.
|
For sharing with groups, the `--group` argument exists.
|
||||||
|
|
||||||
# MFA
|
# MFA
|
||||||
You can setup MFA also using the configuration sub command, only TOTP is supported, there are multiple modes for MFA: `none`, `interactive-totp` and `noninteractive-totp`.
|
You can also set up MFA using the configuration subcommand. Only TOTP is supported, and there are multiple modes for MFA: `none`, `interactive-totp`, and `noninteractive-totp`.
|
||||||
| Mode | Description |
|
| Mode | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|`none`|just errors if challenged for MFA.
|
|`none`|just errors if challenged for MFA.
|
||||||
|`interactive-totp` | prompts for interactive entry of TOTP Codes.
|
|`interactive-totp` | prompts for interactive entry of TOTP Codes.
|
||||||
|`noninteractive-totp` | automatically generates TOTP Codes when challenged, it requires the `mfaTotpToken` flag to be set to your totp Secret, you can configure the behavior using the `mfaDelay`, `mfaRetrys` and `mfaTotpOffset` flags
|
|`noninteractive-totp` | automatically generates TOTP Codes when challenged. It requires the `mfaTotpToken` flag to be set to your totp Secret, you can configure the behavior using the `mfaDelay`, `mfaRetrys` and `mfaTotpOffset` flags
|
||||||
|
|
||||||
|
|
||||||
# Server Verification
|
# Server Verification
|
||||||
To enable Server Verification you need to run `passbolt verify` once, after that the server will always be verified if the same config is used
|
To enable Server Verification, you need to run `passbolt verify` once. After that, the server will always be verified if the same config is used
|
||||||
|
|
||||||
# Scripting
|
# Scripting
|
||||||
For Scripting we have a -j or --json flag to convert the Output for the create, get and list commands to JSON for easier Parsing in Scripts.
|
For Scripting, we have a -j or --json flag to convert the Output for the create, get and list commands to JSON for easier Parsing in Scripts.
|
||||||
|
|
||||||
Note: The JSON Output does not cover Error Messages, you can detect Errors by checking if the Exitcode is not 0
|
Note: The JSON Output does not cover Error Messages. You can detect Errors by checking if the Exitcode is not 0
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
Usage for all Subcommands is [here](https://github.com/passbolt/go-passbolt-cli/wiki/passbolt).
|
Usage for all Subcommands is [here](https://github.com/passbolt/go-passbolt-cli/wiki/passbolt).
|
||||||
And is also available via `man passbolt`
|
It is also available via `man passbolt`
|
||||||
|
|
||||||
|
|
105
resource/get.go
105
resource/get.go
|
@ -4,10 +4,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"al.essio.dev/pkg/shellescape"
|
"al.essio.dev/pkg/shellescape"
|
||||||
"github.com/passbolt/go-passbolt-cli/util"
|
"github.com/passbolt/go-passbolt-cli/util"
|
||||||
"github.com/passbolt/go-passbolt/helper"
|
"github.com/passbolt/go-passbolt/helper"
|
||||||
|
"github.com/pterm/pterm"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,10 +23,24 @@ var ResourceGetCmd = &cobra.Command{
|
||||||
RunE: ResourceGet,
|
RunE: ResourceGet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResourcePermissionCmd Gets Permissions for Passbolt Resource
|
||||||
|
var ResourcePermissionCmd = &cobra.Command{
|
||||||
|
Use: "permission",
|
||||||
|
Short: "Gets Permissions for a Passbolt Resource",
|
||||||
|
Long: `Gets Permissions for a Passbolt Resource`,
|
||||||
|
Aliases: []string{"permissions"},
|
||||||
|
RunE: ResourcePermission,
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
ResourceGetCmd.Flags().String("id", "", "id of Resource to Get")
|
ResourceGetCmd.Flags().String("id", "", "id of Resource to Get")
|
||||||
|
|
||||||
ResourceGetCmd.MarkFlagRequired("id")
|
ResourceGetCmd.MarkFlagRequired("id")
|
||||||
|
|
||||||
|
ResourceGetCmd.AddCommand(ResourcePermissionCmd)
|
||||||
|
ResourcePermissionCmd.Flags().String("id", "", "id of Resource to Get")
|
||||||
|
ResourcePermissionCmd.Flags().StringArrayP("column", "c", []string{"ID", "Aco", "AcoForeignKey", "Aro", "AroForeignKey", "Type"}, "Columns to return, possible Columns:\nID, Aco, AcoForeignKey, Aro, AroForeignKey, Type, CreatedTimestamp, ModifiedTimestamp")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResourceGet(cmd *cobra.Command, args []string) error {
|
func ResourceGet(cmd *cobra.Command, args []string) error {
|
||||||
|
@ -76,3 +94,90 @@ func ResourceGet(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResourcePermission(cmd *cobra.Command, args []string) error {
|
||||||
|
resource, err := cmd.Flags().GetString("id")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
columns, err := cmd.Flags().GetStringArray("column")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(columns) == 0 {
|
||||||
|
return fmt.Errorf("You need to specify atleast one column to return")
|
||||||
|
}
|
||||||
|
jsonOutput, err := cmd.Flags().GetBool("json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := util.GetContext()
|
||||||
|
|
||||||
|
client, err := util.GetClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer client.Logout(context.TODO())
|
||||||
|
cmd.SilenceUsage = true
|
||||||
|
|
||||||
|
permissions, err := client.GetResourcePermissions(ctx, resource)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Listing Permission: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if jsonOutput {
|
||||||
|
outputPermissions := []PermissionJsonOutput{}
|
||||||
|
for i := range permissions {
|
||||||
|
outputPermissions = append(outputPermissions, PermissionJsonOutput{
|
||||||
|
ID: &permissions[i].ID,
|
||||||
|
Aco: &permissions[i].ACO,
|
||||||
|
AcoForeignKey: &permissions[i].ACOForeignKey,
|
||||||
|
Aro: &permissions[i].ARO,
|
||||||
|
AroForeignKey: &permissions[i].AROForeignKey,
|
||||||
|
Type: &permissions[i].Type,
|
||||||
|
CreatedTimestamp: &permissions[i].Created.Time,
|
||||||
|
ModifiedTimestamp: &permissions[i].Modified.Time,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
jsonPermissions, err := json.MarshalIndent(outputPermissions, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(jsonPermissions))
|
||||||
|
} else {
|
||||||
|
data := pterm.TableData{columns}
|
||||||
|
|
||||||
|
for _, permission := range permissions {
|
||||||
|
entry := make([]string, len(columns))
|
||||||
|
for i := range columns {
|
||||||
|
switch strings.ToLower(columns[i]) {
|
||||||
|
case "id":
|
||||||
|
entry[i] = permission.ID
|
||||||
|
case "aco":
|
||||||
|
entry[i] = permission.ACO
|
||||||
|
case "acoforeignkey":
|
||||||
|
entry[i] = permission.ACOForeignKey
|
||||||
|
case "aro":
|
||||||
|
entry[i] = permission.ARO
|
||||||
|
case "aroforeignkey":
|
||||||
|
entry[i] = permission.AROForeignKey
|
||||||
|
case "type":
|
||||||
|
entry[i] = strconv.Itoa(permission.Type)
|
||||||
|
case "createdtimestamp":
|
||||||
|
entry[i] = permission.Created.Format(time.RFC3339)
|
||||||
|
case "modifiedtimestamp":
|
||||||
|
entry[i] = permission.Modified.Format(time.RFC3339)
|
||||||
|
default:
|
||||||
|
cmd.SilenceUsage = false
|
||||||
|
return fmt.Errorf("Unknown Column: %v", columns[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = append(data, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
pterm.DefaultTable.WithHasHeader().WithData(data).Render()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -13,3 +13,14 @@ type ResourceJsonOutput struct {
|
||||||
CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"`
|
CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"`
|
||||||
ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"`
|
ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PermissionJsonOutput struct {
|
||||||
|
ID *string `json:"id,omitempty"`
|
||||||
|
Aco *string `json:"aco,omitempty"`
|
||||||
|
AcoForeignKey *string `json:"aco_foreign_key,omitempty"`
|
||||||
|
Aro *string `json:"aro,omitempty"`
|
||||||
|
AroForeignKey *string `json:"aro_foreign_key,omitempty"`
|
||||||
|
Type *int `json:"type,omitempty"`
|
||||||
|
CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"`
|
||||||
|
ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"`
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue