Skip to content

mcrumm/guss

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Guss

Generate Signed URLs for Google Cloud Storage in Elixir.

Installation

  1. Add guss to your list of dependencies in mix.exs:
def deps do
  [
    {:guss, "~> 0.1.0"}
  ]
end
  1. If you're using Goth for authentication, be sure to configure your credentials:
config :goth,
  json: {:system, "GCP_CREDENTIALS_JSON"}

Documentation

Documentation can be found at https://hexdocs.pm/guss.

Usage

First, create a new resource with your URL components:

iex(1)> url = Guss.new("downloads", "movie.mp4", content_type: "video/mp4")
%Guss.Resource{bucket: "downloads", objectname: "movie.mp4"...}

Then, sign the url:

iex(2)> Guss.sign(url)
{:ok, "https://storage.googleapis.com/downloads/movie.mp4?Expires=1543..."}

Signatures

By default, sign/1 will use the default credentials stored in the Goth config to generate the signature.

To specify an account other than the default, update the :account on the resource:

Guss.sign(%{url | account: "[email protected]"})

It is also possible to use Guss without Goth.

String Components

Expiration

The default :expires value is 1 hour. You can use Guss.expires_in/1 to set a custom future timestamp:

iex(4)> url = Guss.new("downloads", "movie.mp4", expires: Guss.expires_in({1, :day}))
%Guss.Resource{
  account: :default,
  base_url: "https://storage.googleapis.com",
  bucket: "downloads",
  content_md5: nil,
  content_type: nil,
  expires: 1543526299,
  extensions: [],
  http_verb: :get,
  objectname: "movie.mp4"
}

Content Type

Setting the content type in the signature requires the Content-Type header to be set on upload:

Guss.put("downloads", "movie.mp4", content_type: "video/mp4")

Custom Extension Headers

Guss can incorporate custom extension headers into the URL signature.

For instance, to set the canned ACL policy for the object during upload:

Guss.put("bucket", "objectname", acl: :public_read)

Any x-goog- header can be included in the options list...

Guss.put("bucket", "objectname", content_length_range: "0,256")

...including x-goog-meta- headers:

Guss.put("bucket", "objectname", meta: [project: [name: "My Project"]])

Please Note: All headers that appear within the signature MUST also appear in the request to the Signed URL, or the request will be rejected.

Usage without Goth

If you store your authentication data somewhere other than Goth, you can supply your own config module when signing URLs.

First, create a module that can return values for "client_email" and "private_key":

defmodule MyGussConfig do
  def get(account \\ :default, key)
  def get(account, "client_email"), do: fetch_email(account)
  def get(account, "private_key"), do: fetch_private_key(account)
end

Then, create a resource and sign it using your config module:

"bucket"
|> Guss.new("objectname", account: "[email protected]")
|> Guss.sign(config_module: MyGussConfig)