Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/mcrumm/guss

Generate Signed URLs for Google Cloud Storage
https://github.com/mcrumm/guss

Last synced: 27 days ago
JSON representation

Generate Signed URLs for Google Cloud Storage

Awesome Lists containing this project

README

        

# Guss

Generate [Signed URLs](https://cloud.google.com/storage/docs/access-control/signed-url) for Google Cloud Storage in Elixir.

## Installation

1. Add `guss` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:guss, "~> 0.1.0"}
]
end
```

2. If you're using [Goth](https://github.com/peburrows/goth) for authentication, be sure to configure your credentials:

```elixir
config :goth,
json: {:system, "GCP_CREDENTIALS_JSON"}
```

## Documentation

Documentation can be found at [https://hexdocs.pm/guss](https://hexdocs.pm/guss).

## Usage

First, create a new resource with your URL components:

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

Then, sign the url:

```elixir
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:

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

It is also possible to [use Guss without Goth](#usage-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:

```elixir
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:

```elixir
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:

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

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

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

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

```elixir
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"`:

```elixir
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:

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