Skip to content

Commit

Permalink
Add ToznySDKV3 config storage
Browse files Browse the repository at this point in the history
  • Loading branch information
Eli Fabens committed Apr 30, 2021
1 parent c19758c commit e011a65
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 77 deletions.
32 changes: 27 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ type ToznySDKV3 struct {
APIEndpoint string
// Tozny server defined globally unique id for this Client.
ClientID string
config e3dbClients.ClientConfig
}

// ToznySDKConfig wraps parameters needed to configure a ToznySDK
Expand Down Expand Up @@ -686,6 +687,7 @@ func NewToznySDKV3(config ToznySDKConfig) (*ToznySDKV3, error) {
AccountPassword: config.AccountPassword,
APIEndpoint: config.APIEndpoint,
ClientID: config.ClientID,
config: config.ClientConfig,
}, nil
}

Expand Down Expand Up @@ -738,16 +740,15 @@ type LoginActionData = map[string]string

type IdentitySessionIntermediateResponse = identityClient.IdentitySessionRequestResponse

// TozIDLoginRequest is used to login to a TozID account to get a ToznySDKV3 or active TozID session (future plan)
type TozIDLoginRequest struct {
Username string
Password string
RealmName string

APIBaseURL string
APIBaseURL string
LoginHandler func(response *IdentitySessionIntermediateResponse) (LoginActionData, error)
}


//GetSDKV3ForTozIDUser logs in a TozID user and returns the storage client of that user as a ToznySDKV3
func GetSDKV3ForTozIDUser(login TozIDLoginRequest) (*ToznySDKV3, error) {
if login.APIBaseURL == "" {
Expand All @@ -765,7 +766,7 @@ func GetSDKV3ForTozIDUser(login TozIDLoginRequest) (*ToznySDKV3, error) {
realmInfo, err := anonymousClient.RealmInfo(ctx, login.RealmName)
if err != nil {
// TODO: better error message for failure to get realmInfo
return nil, err
return nil, fmt.Errorf("GetSDKV3ForTozIDUser: failed to get realm infor with error %w", err)
}
noteName, encryptionKeys, signingKeys, err := e3dbClients.DeriveIdentityCredentials(username, login.Password, realmInfo.Name, "")
if err != nil {
Expand Down Expand Up @@ -831,10 +832,10 @@ func GetSDKV3ForTozIDUser(login TozIDLoginRequest) (*ToznySDKV3, error) {
reader = &buf
}
request, err := http.NewRequest("POST", sessionResponse.ActionURL, reader)
request.Header.Set("Content-Type", sessionResponse.ContentType)
if err != nil {
return nil, err
}
request.Header.Set("Content-Type", sessionResponse.ContentType)
err = e3dbClients.MakeSignedServiceCall(ctx, &http.Client{}, request, signingKeys, "", &sessionResponse)
if err != nil {
return nil, err
Expand Down Expand Up @@ -925,6 +926,27 @@ type ClientConfig struct {
PrivateSigningKey string `json:"private_signing_key"`
}

// StoreConfigFile stores a ToznySDKV3 config file at the specified path, returning an error if any
func (c *ToznySDKV3) StoreConfigFile(path string) error {
config := ToznySDKJSONConfig{
ConfigFile: ConfigFile{
Version: 2,
APIBaseURL: c.APIEndpoint,
APIKeyID: c.config.APIKey,
APISecret: c.config.APISecret,
ClientID: c.config.ClientID,
ClientEmail: "",
PublicKey: c.config.EncryptionKeys.Public.Material,
PrivateKey: c.config.EncryptionKeys.Private.Material,
},
PublicSigningKey: c.config.SigningKeys.Public.Material,
PrivateSigningKey: c.config.SigningKeys.Private.Material,
AccountUsername: c.AccountUsername,
AccountPassword: c.AccountPassword,
}
return saveJson(path, config)
}

// Register attempts to create a valid TozStore account returning the root client config for the created account and error (if any).
func (c *ToznySDKV3) Register(ctx context.Context, name string, email string, password string, apiURL string) (RegisterAccountResponse, error) {
if apiURL == "" {
Expand Down
20 changes: 14 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func loadConfig(configPath string) (*ClientOpts, error) {
}, nil
}

func saveConfig(configPath string, opts *ClientOpts) error {
func saveJson(configPath string, obj interface{}) error {
configFullPath, err := homedir.Expand(configPath)
if err != nil {
return err
Expand All @@ -126,6 +126,14 @@ func saveConfig(configPath string, opts *ClientOpts) error {
}
defer configFd.Close()

if err = json.NewEncoder(configFd).Encode(&obj); err != nil {
return err
}

return nil
}

func saveConfig(configPath string, opts *ClientOpts) error {
configObj := configFile{
Version: 1,
ClientID: opts.ClientID,
Expand All @@ -137,11 +145,7 @@ func saveConfig(configPath string, opts *ClientOpts) error {
PrivateKey: encodePrivateKey(opts.PrivateKey),
}

if err = json.NewEncoder(configFd).Encode(&configObj); err != nil {
return err
}

return nil
return saveJson(configPath, configObj)
}

func fileExists(name string) (bool, error) {
Expand Down Expand Up @@ -214,3 +218,7 @@ func LoadConfigFile(configPath string) (ToznySDKJSONConfig, error) {
}
return config, nil
}

func StoreConfigFile(configPath string, config ToznySDKJSONConfig) error {
return saveJson(configPath, config)
}
108 changes: 54 additions & 54 deletions example_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,77 @@ package e3db_test
// this code, it will share text with Tozny in an end-to-end encrypted manner.

import (
"context"
"fmt"
"github.com/tozny/e3db-go/v2"
"log"
"context"
"fmt"
"github.com/tozny/e3db-go/v2"
"log"
)

func chk(err error) {
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
}

func printRecords(recordType string) {
client, err := e3db.GetDefaultClient()
chk(err)
client, err := e3db.GetDefaultClient()
chk(err)

// Query for all records and print them out
query := e3db.Q{} // queries all records
if recordType != "" {
query = e3db.Q{ContentTypes: []string{recordType}}
}
cursor := client.Query(context.Background(), query)
for {
record, err := cursor.Next()
if err == e3db.Done {
break
} else if err != nil {
chk(err)
}
fmt.Println("\t" + record.Meta.RecordID + " " + record.Meta.Type)
}
// Query for all records and print them out
query := e3db.Q{} // queries all records
if recordType != "" {
query = e3db.Q{ContentTypes: []string{recordType}}
}
cursor := client.Query(context.Background(), query)
for {
record, err := cursor.Next()
if err == e3db.Done {
break
} else if err != nil {
chk(err)
}
fmt.Println("\t" + record.Meta.RecordID + " " + record.Meta.Type)
}
}

func Example() {

// Accessing the default profile.
// You must run e3db RegisterClient before this will work:
client, err := e3db.GetDefaultClient()
chk(err)
// Accessing the default profile.
// You must run e3db RegisterClient before this will work:
client, err := e3db.GetDefaultClient()
chk(err)

fmt.Println("Current list of records:")
printRecords("")
fmt.Println("Current list of records:")
printRecords("")

// Create a new "feedback" record; this is the type the CLI uses
feedbackData := make(map[string]string)
feedbackData["comment"] = "This is some example feedback!"
feedbackData["interface"] = "Go Example Code"
record, err := client.Write(context.Background(), "feedback", feedbackData, nil)
chk(err)
// Create a new "feedback" record; this is the type the CLI uses
feedbackData := make(map[string]string)
feedbackData["comment"] = "This is some example feedback!"
feedbackData["interface"] = "Go Example Code"
record, err := client.Write(context.Background(), "feedback", feedbackData, nil)
chk(err)

// Read back the feedback we just put into the database
newFeedbackRecord, err := client.Read(context.Background(), record.Meta.RecordID)
chk(err)
fmt.Println("Read record id " + record.Meta.RecordID + ": " + newFeedbackRecord.Data["comment"])
// Read back the feedback we just put into the database
newFeedbackRecord, err := client.Read(context.Background(), record.Meta.RecordID)
chk(err)
fmt.Println("Read record id " + record.Meta.RecordID + ": " + newFeedbackRecord.Data["comment"])

// Fetch the Tozny feedback email address public key and client ID
feedbackClient, err := client.GetClientInfo(context.Background(), "db1744b9-3fb6-4458-a291-0bc677dba08b")
chk(err)
// Fetch the Tozny feedback email address public key and client ID
feedbackClient, err := client.GetClientInfo(context.Background(), "db1744b9-3fb6-4458-a291-0bc677dba08b")
chk(err)

// Share all "feedback" records with that user ID.
err = client.Share(context.Background(), "feedback", feedbackClient.ClientID)
chk(err)
// Share all "feedback" records with that user ID.
err = client.Share(context.Background(), "feedback", feedbackClient.ClientID)
chk(err)

fmt.Println("Current list of records after adding:")
printRecords("feedback")
fmt.Println("Current list of records after adding:")
printRecords("feedback")

// Delete the record we just created to keep things tidy.
// Comment out this line if you want to keep it
err = client.Delete(context.Background(), record.Meta.RecordID, record.Meta.Version)
chk(err)
// Delete the record we just created to keep things tidy.
// Comment out this line if you want to keep it
err = client.Delete(context.Background(), record.Meta.RecordID, record.Meta.Version)
chk(err)

fmt.Println("Current list of records after deleting:")
printRecords("feedback")
fmt.Println("Current list of records after deleting:")
printRecords("feedback")
}
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
module github.com/tozny/e3db-go/v2

go 1.13
go 1.15

require (
github.com/google/uuid v1.1.0
github.com/jawher/mow.cli v1.0.4
github.com/mitchellh/go-homedir v1.0.0
github.com/stretchr/testify v1.6.1 // indirect
github.com/tozny/e3db-clients-go v0.0.144-0.20210428154208-cc5c7c2fe4ee
github.com/tozny/e3db-clients-go v0.0.144
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
)

replace github.com/tozny/e3db-clients-go => ../e3db-clients-go
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tozny/e3db-clients-go v0.0.143 h1:RCCN+fFoKOIwLasxT3JGnq8Ceczk64/ZvImEsWFclfA=
github.com/tozny/e3db-clients-go v0.0.143/go.mod h1:xqnK5S5r0qLrKCUms5Mi/3oij2ppNg2lk/8iggyn7IQ=
github.com/tozny/e3db-clients-go v0.0.144 h1:Y4j/fYRZ+KAZzMPnkEhF8QLipGPCBUUDMNK8712y3J4=
github.com/tozny/e3db-clients-go v0.0.144/go.mod h1:xqnK5S5r0qLrKCUms5Mi/3oij2ppNg2lk/8iggyn7IQ=
github.com/tozny/utils-go v0.0.35 h1:gPvhlQ8QCoLBUjIx1COfYy6o4dfSM8Lrh+2FV9Ask+g=
github.com/tozny/utils-go v0.0.35/go.mod h1:SHi9wnpPEEzAxbwcBhRd+jW32r+gY6S+AcWweuGytRw=
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down
1 change: 0 additions & 1 deletion identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ func (i *Identity) DeriveCredentails(password string, nameSalt string) (string,
return e3dbClients.DeriveIdentityCredentials(i.Username, password, i.Realm.Name, nameSalt)
}


func (i *Identity) writePasswordNote(password string) (*storageClient.Note, error) {
info, err := i.Realm.Info()
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (

func TestToznySDKV3_Login(t *testing.T) {
request := TozIDLoginRequest{
Username: "",
Password: "",
RealmName: "",
APIBaseURL: "https://api.e3db.com",
Username: "",
Password: "",
RealmName: "",
APIBaseURL: "https://api.e3db.com",
LoginHandler: mfaHandler,
}
sdk, err := GetSDKV3ForTozIDUser(request)
Expand All @@ -27,4 +27,4 @@ func mfaHandler(sessionResponse *IdentitySessionIntermediateResponse) (LoginActi
return totpValue, nil
}
return nil, fmt.Errorf("mfaHandler cannot support \"%s\" action types", sessionResponse.LoginActionType)
}
}

0 comments on commit e011a65

Please sign in to comment.