Skip to content

Commit

Permalink
Merge pull request #63 from Azure/new-shared-key-return-error
Browse files Browse the repository at this point in the history
Avoid panics in NewSharedKeyCredential
  • Loading branch information
JeffreyRichter authored Aug 18, 2018
2 parents 91c041e + d795ea3 commit b13c8df
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 62 deletions.
6 changes: 3 additions & 3 deletions 2018-03-28/azblob/zc_credential_shared_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import (

// NewSharedKeyCredential creates an immutable SharedKeyCredential containing the
// storage account's name and either its primary or secondary key.
func NewSharedKeyCredential(accountName, accountKey string) *SharedKeyCredential {
func NewSharedKeyCredential(accountName, accountKey string) (*SharedKeyCredential, error) {
bytes, err := base64.StdEncoding.DecodeString(accountKey)
if err != nil {
panic(err)
return &SharedKeyCredential{}, err
}
return &SharedKeyCredential{accountName: accountName, accountKey: bytes}
return &SharedKeyCredential{accountName: accountName, accountKey: bytes}, nil
}

// SharedKeyCredential contains an account's name and its primary or secondary key.
Expand Down
136 changes: 99 additions & 37 deletions 2018-03-28/azblob/zt_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ func Example() {
accountName, accountKey := accountInfo()

// Use your Storage account's name and key to create a credential object; this is used to access your account.
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}

// Create a request pipeline that is used to process HTTP(S) requests and responses. It requires
// your account credentials. In more advanced scenarios, you can configure telemetry, retry policies,
Expand All @@ -58,7 +61,7 @@ func Example() {
containerURL := serviceURL.NewContainerURL("mycontainer") // Container names require lowercase

// Create the container on the service (with no metadata and no public access)
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
_, err = containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -278,7 +281,10 @@ func ExampleAccountSASSignatureValues() {
accountName, accountKey := accountInfo()

// Use your Storage account's name and key to create a credential object; this is required to sign a SAS.
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}

// Set the desired SAS signature values and sign them with the shared key credentials to get the SAS query parameters.
sasQueryParams := azblob.AccountSASSignatureValues{
Expand Down Expand Up @@ -316,7 +322,10 @@ func ExampleBlobSASSignatureValues() {
accountName, accountKey := accountInfo()

// Use your Storage account's name and key to create a credential object; this is required to sign a SAS.
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}

// This is the name of the container and blob that we're creating a SAS to.
containerName := "mycontainer" // Container names require lowercase
Expand Down Expand Up @@ -364,7 +373,10 @@ func ExampleContainerURL_SetContainerAccessPolicy() {
accountName, accountKey := accountInfo()

// Use your Storage account's name and key to create a credential object; this is used to access your account.
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}

// Create an ContainerURL object that wraps the container's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer", accountName))
Expand All @@ -374,7 +386,7 @@ func ExampleContainerURL_SetContainerAccessPolicy() {
ctx := context.Background() // This example uses a never-expiring context

// Create the container (with no metadata and no public access)
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
_, err = containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -424,7 +436,11 @@ func ExampleBlobAccessConditions() {

// Create a BlockBlobURL object that wraps a blob's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/Data.txt", accountName))
blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

Expand Down Expand Up @@ -477,16 +493,19 @@ func ExampleMetadata_containers() {

// Create a ContainerURL object that wraps a soon-to-be-created container's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer", accountName))
containerURL := azblob.NewContainerURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
containerURL := azblob.NewContainerURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

// Create a container with some metadata (string key/value pairs)
// NOTE: Metadata key names are always converted to lowercase before being sent to the Storage Service.
// Therefore, you should always use lowercase letters; especially when querying a map for a metadata key.
creatingApp, _ := os.Executable()
_, err := containerURL.Create(ctx, azblob.Metadata{"author": "Jeffrey", "app": creatingApp}, azblob.PublicAccessNone)
_, err = containerURL.Create(ctx, azblob.Metadata{"author": "Jeffrey", "app": creatingApp}, azblob.PublicAccessNone)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -521,16 +540,19 @@ func ExampleMetadata_blobs() {

// Create a ContainerURL object that wraps a soon-to-be-created blob's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/ReadMe.txt", accountName))
blobURL := azblob.NewBlockBlobURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

// Create a blob with metadata (string key/value pairs)
// NOTE: Metadata key names are always converted to lowercase before being sent to the Storage Service.
// Therefore, you should always use lowercase letters; especially when querying a map for a metadata key.
creatingApp, _ := os.Executable()
_, err := blobURL.Upload(ctx, strings.NewReader("Some text"), azblob.BlobHTTPHeaders{},
_, err = blobURL.Upload(ctx, strings.NewReader("Some text"), azblob.BlobHTTPHeaders{},
azblob.Metadata{"author": "Jeffrey", "app": creatingApp}, azblob.BlobAccessConditions{})
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -569,13 +591,16 @@ func ExampleBlobHTTPHeaders() {

// Create a ContainerURL object that wraps a soon-to-be-created blob's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/ReadMe.txt", accountName))
blobURL := azblob.NewBlockBlobURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

// Create a blob with HTTP headers
_, err := blobURL.Upload(ctx, strings.NewReader("Some text"),
_, err = blobURL.Upload(ctx, strings.NewReader("Some text"),
azblob.BlobHTTPHeaders{
ContentType: "text/html; charset=utf-8",
ContentDisposition: "attachment",
Expand Down Expand Up @@ -616,8 +641,11 @@ func ExampleBlockBlobURL() {

// Create a ContainerURL object that wraps a soon-to-be-created blob's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/MyBlockBlob.txt", accountName))
blobURL := azblob.NewBlockBlobURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

Expand Down Expand Up @@ -655,7 +683,7 @@ func ExampleBlockBlobURL() {
}

// After all the blocks are uploaded, atomically commit them to the blob.
_, err := blobURL.CommitBlockList(ctx, base64BlockIDs, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
_, err = blobURL.CommitBlockList(ctx, base64BlockIDs, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -691,10 +719,14 @@ func ExampleAppendBlobURL() {

// Create a ContainerURL object that wraps a soon-to-be-created blob's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/MyAppendBlob.txt", accountName))
appendBlobURL := azblob.NewAppendBlobURL(*u, azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
appendBlobURL := azblob.NewAppendBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context
_, err := appendBlobURL.Create(ctx, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
_, err = appendBlobURL.Create(ctx, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -727,11 +759,14 @@ func ExamplePageBlobURL() {

// Create a ContainerURL object that wraps a soon-to-be-created blob's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/MyPageBlob.txt", accountName))
blobURL := azblob.NewPageBlobURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewPageBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context
_, err := blobURL.Create(ctx, azblob.PageBlobPageBytes*4, 0, azblob.BlobHTTPHeaders{},
_, err = blobURL.Create(ctx, azblob.PageBlobPageBytes*4, 0, azblob.BlobHTTPHeaders{},
azblob.Metadata{}, azblob.BlobAccessConditions{})
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -790,16 +825,19 @@ func Example_blobSnapshots() {

// Create a ContainerURL object to a container where we'll create a blob and its snapshot.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer", accountName))
containerURL := azblob.NewContainerURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
containerURL := azblob.NewContainerURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

// Create a BlockBlobURL object to a blob in the container.
baseBlobURL := containerURL.NewBlockBlobURL("Original.txt")

ctx := context.Background() // This example uses a never-expiring context

// Create the original blob:
_, err := baseBlobURL.Upload(ctx, strings.NewReader("Some text"), azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
_, err = baseBlobURL.Upload(ctx, strings.NewReader("Some text"), azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -875,7 +913,10 @@ func Example_blobSnapshots() {
func Example_progressUploadDownload() {
// Create a request pipeline using your Storage account's name and account key.
accountName, accountKey := accountInfo()
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
p := azblob.NewPipeline(credential, azblob.PipelineOptions{})

// From the Azure portal, get your Storage account blob service URL endpoint.
Expand All @@ -892,7 +933,7 @@ func Example_progressUploadDownload() {
requestBody := strings.NewReader("Some text to write")

// Wrap the request body in a RequestBodyProgress and pass a callback function for progress reporting.
_, err := blobURL.Upload(ctx,
_, err = blobURL.Upload(ctx,
pipeline.NewRequestBodyProgress(requestBody, func(bytesTransferred int64) {
fmt.Printf("Wrote %d of %d bytes.", bytesTransferred, requestBody.Len())
}),
Expand Down Expand Up @@ -930,8 +971,11 @@ func ExampleBlobURL_startCopy() {
// Create a ContainerURL object to a container where we'll create a blob and its snapshot.
// Create a BlockBlobURL object to a blob in the container.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/CopiedBlob.bin", accountName))
blobURL := azblob.NewBlobURL(*u,
azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

Expand Down Expand Up @@ -971,7 +1015,11 @@ func ExampleUploadFileToBlockBlobAndDownloadItBack() {

// Create a BlockBlobURL object to a blob in the container (we assume the container already exists).
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/BigBlockBlob.bin", accountName))
blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

Expand Down Expand Up @@ -1015,7 +1063,11 @@ func ExampleBlobUrl_Download() {

// Create a BlobURL object to a blob in the container (we assume the container & blob already exist).
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/BigBlob.bin", accountName))
blobURL := azblob.NewBlobURL(*u, azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blobURL := azblob.NewBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

contentLength := int64(0) // Used for progress reporting to report the total number of bytes being downloaded.

Expand Down Expand Up @@ -1052,7 +1104,11 @@ func ExampleUploadStreamToBlockBlob() {

// Create a BlockBlobURL object to a blob in the container (we assume the container already exists).
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/BigBlockBlob.bin", accountName))
blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(azblob.NewSharedKeyCredential(accountName, accountKey), azblob.PipelineOptions{}))
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}
blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

ctx := context.Background() // This example uses a never-expiring context

Expand All @@ -1064,7 +1120,7 @@ func ExampleUploadStreamToBlockBlob() {
// Perform UploadStreamToBlockBlob
bufferSize := 2 * 1024 * 1024 // Configure the size of the rotating buffers that are used when uploading
maxBuffers := 3 // Configure the number of rotating buffers that are used when uploading
_, err := azblob.UploadStreamToBlockBlob(ctx, bytes.NewReader(data), blockBlobURL,
_, err = azblob.UploadStreamToBlockBlob(ctx, bytes.NewReader(data), blockBlobURL,
azblob.UploadStreamToBlockBlobOptions{BufferSize: bufferSize, MaxBuffers: maxBuffers})

// Verify that upload was successful
Expand All @@ -1082,7 +1138,10 @@ func ExampleLeaseContainer() {
accountName, accountKey := accountInfo()

// Use your Storage account's name and key to create a credential object; this is used to access your account.
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}

// Create an ContainerURL object that wraps the container's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer", accountName))
Expand Down Expand Up @@ -1151,7 +1210,10 @@ func ExampleListBlobsHierarchy() {
accountName, accountKey := accountInfo()

// Use your Storage account's name and key to create a credential object; this is used to access your account.
credential := azblob.NewSharedKeyCredential(accountName, accountKey)
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil {
log.Fatal(err)
}

// Create an ContainerURL object that wraps the container's URL and a default pipeline.
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer", accountName))
Expand Down
Loading

0 comments on commit b13c8df

Please sign in to comment.