diff --git a/apitypes.go b/apitypes.go index 53a76ce..f7508d1 100644 --- a/apitypes.go +++ b/apitypes.go @@ -225,3 +225,28 @@ const ( type FileStatus struct { File } + +type CreateKeyRequest struct { + AccountID string `json:"accountId"` + Capabilities []string `json:"capabilities"` + KeyName string `json:"keyName"` + ValidDurationInSeconds int `json:"validDurationInSeconds,omitempty"` + BucketId string `json:"bucketId,omitempty"` + NamePrefix string `json:"namePrefix,omitempty"` +} + +type ApplicationKeyResponse struct { + KeyName string `json:"keyName"` + ApplicationKeyId string `json:"applicationKeyId"` + ApplicationKey string `json:"applicationKey"` + Capabilities []string `json:"capabilities"` + AccountID string `json:"accountId"` + ExpirationTimestamp int64 `json:"expirationTimestamp"` + BucketId string `json:"bucketId"` + NamePrefix string `json:"namePrefix"` + Options []string `json:"options"` +} + +type DeleteKeyRequest struct { + ApplicationKeyId string `json:"applicationKeyId"` +} diff --git a/buckets.go b/buckets.go index 7f6c0fd..6dfea6e 100644 --- a/buckets.go +++ b/buckets.go @@ -108,7 +108,7 @@ func (b *B2) ListBuckets() ([]*Bucket, error) { case AllPrivate: case Snapshot: default: - return nil, errors.New("Uncrecognised bucket type: " + string(bucket.BucketType)) + return nil, errors.New("Unrecognized bucket type: " + string(bucket.BucketType)) } buckets[i] = bucket @@ -231,3 +231,45 @@ func (b *Bucket) ReturnUploadAuth(uploadAuth *UploadAuth) { } } } + +// CreateApplicationKey creates application key +// It is possible to limit application key capabilities by defining an +// array with allowed permission +// (which can be find here https://www.backblaze.com/apidocs/b2-create-key) +// This function to work requires master application key to +// be used for authenticaion +func (b *B2) CreateApplicationKey(keyDetails *CreateKeyRequest) (*ApplicationKeyResponse, error) { + request := &CreateKeyRequest{ + AccountID: b.AccountID, + Capabilities: keyDetails.Capabilities, + KeyName: keyDetails.KeyName, + ValidDurationInSeconds: keyDetails.ValidDurationInSeconds, + BucketId: keyDetails.BucketId, + NamePrefix: keyDetails.NamePrefix, + } + + response := &ApplicationKeyResponse{} + + if err := b.apiRequest("b2_create_key", request, response); err != nil { + return nil, err + } + + return response, nil +} + +// DeleteApplicationKey deletes application keys by providing applicationKeyID +// This function to work requires master application key to +// be used for authenticaion +func (b *B2) DeleteApplicationKey(applicationKeyId string) (*ApplicationKeyResponse, error) { + request := &DeleteKeyRequest{ + ApplicationKeyId: applicationKeyId, + } + + response := &ApplicationKeyResponse{} + + if err := b.apiRequest("b2_delete_key", request, response); err != nil { + return nil, err + } + + return response, nil +} diff --git a/buckets_test.go b/buckets_test.go index 7019751..84a82a3 100644 --- a/buckets_test.go +++ b/buckets_test.go @@ -2,6 +2,7 @@ package backblaze import ( "testing" + "time" ) func TestListBuckets(T *testing.T) { @@ -51,3 +52,69 @@ func TestListBuckets(T *testing.T) { T.Errorf("Bucket ID does not match: expected %q, saw %q", bucketID, buckets[0].ID) } } + +func TestCreateApplicationKey(T *testing.T) { + + accountID := "test" + + keyName := "my-new-key" + applicationKeyId := "fffff000123" + applicationKey := "abcdfxyz" + + timestampNow := time.Now().Unix() + keyValidDurationInSeconds := 3600 + expirationTimeStamp := timestampNow + int64(keyValidDurationInSeconds) + + client, server := prepareResponses([]response{ + {code: 200, body: authorizeAccountResponse{ + AccountID: accountID, + APIEndpoint: "http://api.url", + AuthorizationToken: "testToken", + DownloadURL: "http://download.url", + }}, + {code: 200, body: ApplicationKeyResponse{ + KeyName: keyName, + ApplicationKeyId: applicationKeyId, + ApplicationKey: applicationKey, + ExpirationTimestamp: expirationTimeStamp, + }}, + }) + defer server.Close() + + b2 := &B2{ + Credentials: Credentials{ + AccountID: accountID, + ApplicationKey: "test", + }, + Debug: testing.Verbose(), + httpClient: *client, + host: server.URL, + } + + appkey, err := b2.CreateApplicationKey(&CreateKeyRequest{ + Capabilities: []string{"listAllBucketNames", "listKeys"}, + KeyName: keyName, + ValidDurationInSeconds: keyValidDurationInSeconds, + }) + + if err != nil { + T.Fatal(err) + } + + if appkey.KeyName != keyName { + T.Errorf("Expected to get keyName '%s', received '%s'", keyName, appkey.KeyName) + } + + if appkey.ApplicationKeyId != applicationKeyId { + T.Errorf("Expected to get applicationKeyId '%s', received '%s'", applicationKeyId, appkey.ApplicationKeyId) + } + + if appkey.ApplicationKey != applicationKey { + T.Errorf("Expected to get applicationKey '%s', received '%s'", applicationKey, appkey.ApplicationKey) + } + + if appkey.ExpirationTimestamp != expirationTimeStamp { + T.Errorf("Expected to get ExpirationTimestamp '%d', received '%d'", expirationTimeStamp, appkey.ExpirationTimestamp) + } + +}