1package azblob_test 2 3import ( 4 "bytes" 5 "github.com/Azure/azure-storage-blob-go/azblob" 6 chk "gopkg.in/check.v1" 7 "strings" 8 "time" 9) 10 11func (s *aztestsSuite) TestSnapshotSAS(c *chk.C) { 12 //Generate URLs ---------------------------------------------------------------------------------------------------- 13 bsu := getBSU() 14 containerURL, containerName := getContainerURL(c, bsu) 15 blobURL, blobName := getBlockBlobURL(c, containerURL) 16 17 _, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone) 18 defer containerURL.Delete(ctx, azblob.ContainerAccessConditions{}) 19 if err != nil { 20 c.Fatal(err) 21 } 22 23 //Create file in container, download from snapshot to test. -------------------------------------------------------- 24 burl := containerURL.NewBlockBlobURL(blobName) 25 data := "Hello world!" 26 27 _, err = burl.Upload(ctx, strings.NewReader(data), azblob.BlobHTTPHeaders{ContentType: "text/plain"}, azblob.Metadata{}, azblob.BlobAccessConditions{}) 28 if err != nil { 29 c.Fatal(err) 30 } 31 32 //Create a snapshot & URL 33 createSnapshot, err := burl.CreateSnapshot(ctx, azblob.Metadata{}, azblob.BlobAccessConditions{}) 34 if err != nil { 35 c.Fatal(err) 36 } 37 38 //Format snapshot time 39 snapTime, err := time.Parse(azblob.SnapshotTimeFormat, createSnapshot.Snapshot()) 40 if err != nil { 41 c.Fatal(err) 42 } 43 44 //Get credentials & current time 45 currentTime := time.Now().UTC() 46 credential, err := getGenericCredential("") 47 if err != nil { 48 c.Fatal("Invalid credential") 49 } 50 51 //Create SAS query 52 snapSASQueryParams, err := azblob.BlobSASSignatureValues{ 53 StartTime: currentTime, 54 ExpiryTime: currentTime.Add(48 * time.Hour), 55 SnapshotTime: snapTime, 56 Permissions: "racwd", 57 ContainerName: containerName, 58 BlobName: blobName, 59 Protocol: azblob.SASProtocolHTTPS, 60 }.NewSASQueryParameters(credential) 61 if err != nil { 62 c.Fatal(err) 63 } 64 65 //Attach SAS query to block blob URL 66 p := azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{}) 67 snapParts := azblob.NewBlobURLParts(blobURL.URL()) 68 snapParts.SAS = snapSASQueryParams 69 sburl := azblob.NewBlockBlobURL(snapParts.URL(), p) 70 71 //Test the snapshot 72 downloadResponse, err := sburl.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false) 73 if err != nil { 74 c.Fatal(err) 75 } 76 77 downloadedData := &bytes.Buffer{} 78 reader := downloadResponse.Body(azblob.RetryReaderOptions{}) 79 downloadedData.ReadFrom(reader) 80 reader.Close() 81 82 c.Assert(data, chk.Equals, downloadedData.String()) 83 84 //Try to delete snapshot ------------------------------------------------------------------------------------------- 85 _, err = sburl.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{}) 86 if err != nil { //This shouldn't fail. 87 c.Fatal(err) 88 } 89 90 //Create a normal blob and attempt to use the snapshot SAS against it (assuming failure) --------------------------- 91 //If this succeeds, it means a normal SAS token was created. 92 93 fsburl := containerURL.NewBlockBlobURL("failsnap") 94 _, err = fsburl.Upload(ctx, strings.NewReader(data), azblob.BlobHTTPHeaders{ContentType: "text/plain"}, azblob.Metadata{}, azblob.BlobAccessConditions{}) 95 if err != nil { 96 c.Fatal(err) //should succeed to create the blob via normal auth means 97 } 98 99 fsburlparts := azblob.NewBlobURLParts(fsburl.URL()) 100 fsburlparts.SAS = snapSASQueryParams 101 fsburl = azblob.NewBlockBlobURL(fsburlparts.URL(), p) //re-use fsburl as we don't need the sharedkey version anymore 102 103 resp, err := fsburl.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{}) 104 if err == nil { 105 c.Fatal(resp) //This SHOULD fail. Otherwise we have a normal SAS token... 106 } 107} 108