Skip to content

Commit

Permalink
Update SDK Registration Routine
Browse files Browse the repository at this point in the history
Add support for registration tokens to the SDK and update integration tests:
- Registration via a token is explicitly tested
- Both the test client and sharing client are dynamically registered
  • Loading branch information
Eric Mann committed Aug 22, 2017
1 parent 385794c commit 4bfe502
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 6 deletions.
59 changes: 59 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,25 @@ type ClientInfo struct {
Validated bool `json:"validated"`
}

// ClientDetails contains information about a newly-registered E3DB client
type ClientDetails struct {
ClientID string `json:"client_id"`
ApiKeyID string `json:"api_key_id"`
ApiSecret string `json:"api_secret"`
PublicKey clientKey `json:"public_key"`
Name string `json:"name"`
}

type clientRegistrationInfo struct {
Name string `json:"name"`
PublicKey clientKey `json:"public_key"`
}

type clientRegistrationRequest struct {
Token string `json:"token"`
Client clientRegistrationInfo `json:"client"`
}

// Meta contains meta-information about an E3DB record, such as
// who wrote it, when it was written, and the type of the data stored.
type Meta struct {
Expand Down Expand Up @@ -132,6 +151,46 @@ func GetClient(opts ClientOpts) (*Client, error) {
}, nil
}

// RegisterClient creates a new client for a given InnoVault account
func RegisterClient(registrationToken string, clientName string, publicKey clientKey, apiURL string) (*ClientDetails, error) {
if apiURL == "" {
apiURL = defaultStorageURL
}

request := &clientRegistrationRequest{
Token: registrationToken,
Client: clientRegistrationInfo{
Name: clientName,
PublicKey: publicKey,
},
}

buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(request)
req, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/account/e3db/clients/register", apiURL), buf)

if err != nil {
return nil, err
}

client := &http.Client{}

resp, err := client.Do(req)
if err != nil {
return nil, err
}

defer closeResp(resp)

var details *ClientDetails
if err := json.NewDecoder(resp.Body).Decode(&details); err != nil {
closeResp(resp)
return nil, err
}

return details, nil
}

func (c *Client) apiURL() string {
if c.Options.APIBaseURL == "" {
return defaultStorageURL
Expand Down
87 changes: 81 additions & 6 deletions client_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,61 @@ func dieErr(err error) {
}

func setup() {
opts, err := GetConfig("integration-test")
apiURL := os.Getenv("API_URL")
token := os.Getenv("REGISTRATION_TOKEN")

clientName := "test-client-" + base64Encode(randomSecretKey()[:8])
shareClientName := "share-client-" + base64Encode(randomSecretKey()[:8])

pub, priv, err := generateKeyPair()
if err != nil {
dieErr(err)
}
pubKey := clientKey{Curve25519: base64Encode(pub[:])}

opts.Logging = false
pub2, priv2, err := generateKeyPair()
if err != nil {
dieErr(err)
}
pubKey2 := clientKey{Curve25519: base64Encode(pub2[:])}

client, err = GetClient(*opts)
clientDetails, err := RegisterClient(token, clientName, pubKey, apiURL)
if err != nil {
dieErr(err)
}

// Load another client for later sharing tests
opts, err = GetConfig("integration-test-shared")
shareClientDetails, err := RegisterClient(token, shareClientName, pubKey2, apiURL)
if err != nil {
dieErr(err)
}

opts.Logging = false
opts := &ClientOpts{
ClientID: clientDetails.ClientID,
ClientEmail: "",
APIKeyID: clientDetails.ApiKeyID,
APISecret: clientDetails.ApiSecret,
PublicKey: pub,
PrivateKey: priv,
APIBaseURL: apiURL,
Logging: false,
}

client, err = GetClient(*opts)
if err != nil {
dieErr(err)
}

// Load another client for later sharing tests
opts = &ClientOpts{
ClientID: shareClientDetails.ClientID,
ClientEmail: "",
APIKeyID: shareClientDetails.ApiKeyID,
APISecret: shareClientDetails.ApiSecret,
PublicKey: pub2,
PrivateKey: priv2,
APIBaseURL: apiURL,
Logging: false,
}

var client2 *Client
client2, err = GetClient(*opts)
Expand All @@ -70,6 +106,45 @@ func shutdown() {

}

func TestRegistration(t *testing.T) {
apiURL := os.Getenv("API_URL")
token := os.Getenv("REGISTRATION_TOKEN")

pub, _, err := generateKeyPair()
if err != nil {
t.Fatal(err)
}

pubKey := clientKey{Curve25519: base64Encode(pub[:])}
clientName := "test-client-" + base64Encode(randomSecretKey()[:8])

client, err := RegisterClient(token, clientName, pubKey, apiURL)

if err != nil {
t.Fatal(err)
}

if clientName != client.Name {
t.Errorf("Client name does not match: %s != %s", clientName, client.Name)
}

if pubKey.Curve25519 != client.PublicKey.Curve25519 {
t.Errorf("Client keys do not match: %s != %s", pubKey.Curve25519, client.PublicKey.Curve25519)
}

if client.ClientID == "" {
t.Error("Client ID is not set")
}

if client.ApiKeyID == "" {
t.Error("API Key ID is not set")
}

if client.ApiSecret == "" {
t.Error("API Secret is not set")
}
}

func TestGetClientInfo(t *testing.T) {
info, err := client.GetClientInfo(context.Background(), client.Options.ClientID)
if err != nil {
Expand Down

0 comments on commit 4bfe502

Please sign in to comment.