gcs-signer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +57 -0
- data/lib/gcs_signer.rb +122 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9da9710c3ec0d2781bb3d0002fc104a9f898ad9
|
4
|
+
data.tar.gz: 8027a48a1276f076f9d0a46a5bd9aa0841da712e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3b1303e21df8a93d2cd23a8ef1636a30d79ff3238643524adfc52efa7b082df53fdcb2d5fbdaa85e6a89b2ef06323d31d481a906106a895ca42bc6b7fb4687d5
|
7
|
+
data.tar.gz: 8e37da7d200265cdeb64ae82a0395a6c66a26ae92b1f9bb7d1e25698b30a349be783d372114cacb2605a3238e9afcb99fa8909fd8f4586421dbe7edb77edda6f
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# gcs-signer
|
2
|
+
|
3
|
+
Simple signed URL generator for Google Cloud Storage.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
* No additional gems required.
|
8
|
+
* No network connection required to generate signed URL.
|
9
|
+
* Can read JSON service_account credentials from environment variables. So it can be used with [google-cloud-ruby](https://github.com/GoogleCloudPlatform/google-cloud-ruby) without additional configurations.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
```shell
|
14
|
+
gem install gcs-signer
|
15
|
+
```
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
If you already configured `GOOGLE_CLOUD_KEYFILE` or `GOOGLE_CLOUD_KEYFILE_JSON` for google-cloud-ruby gem, just
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
signer = GcsSigner.new
|
23
|
+
```
|
24
|
+
|
25
|
+
or you can give path of the service_account json file, or contents of it.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
signer = GcsSigner.new path: "/home/leo/path/to/service_account.json"
|
29
|
+
|
30
|
+
signer = GcsSigner.new json_string: '{ "type": "service_account", ...'
|
31
|
+
```
|
32
|
+
|
33
|
+
then `#sign_url` to generate signed URL.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# The signed URL is valid for 5 minutes by default.
|
37
|
+
signer.sign_url "bucket-name", "path/to/object"
|
38
|
+
|
39
|
+
# You can specify timestamps or how many seconds the signed URL is valid for.
|
40
|
+
signer.sign_url "bucket-name", "object-name",
|
41
|
+
expires: Time.new(2016, 12, 26, 14, 31, 48)
|
42
|
+
|
43
|
+
signer.sign_url "bucket-name", "object_name", valid_for: 600
|
44
|
+
|
45
|
+
# If you use AcriveSupport in your project, you can also do some magic like:
|
46
|
+
signer.sign_url "buekct", "object", valid_for: 45.minutes
|
47
|
+
|
48
|
+
# See https://cloud.google.com/storage/docs/access-control/signed-urls
|
49
|
+
# for other avaliable options.
|
50
|
+
signer.sign_url "buekct", "object", google_access_id: "sangwon@sha.kr",
|
51
|
+
method: "PUT", content_type: "text/plain",
|
52
|
+
md5: "beefbeef..."
|
53
|
+
```
|
54
|
+
|
55
|
+
## License
|
56
|
+
|
57
|
+
gcs-signer is distributed under the MIT License.
|
data/lib/gcs_signer.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "uri"
|
3
|
+
require "openssl"
|
4
|
+
require "base64"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
# Creates signed_url for a file on Google Cloud Storage.
|
8
|
+
#
|
9
|
+
# signer = GcsSigner.new(path: "/Users/leo/private/service_account.json")
|
10
|
+
# signer.sign "your-bucket", "object/name"
|
11
|
+
# # => "https://storage.googleapis.com/your-bucket/object/name?..."
|
12
|
+
class GcsSigner
|
13
|
+
VERSION = "0.1.0"
|
14
|
+
|
15
|
+
# gcs-signer requires credential that can access to GCS.
|
16
|
+
# [path] the path of the service_account json file.
|
17
|
+
# [json_string] ...or the content of the service_account json file.
|
18
|
+
#
|
19
|
+
# or if you also use \+google-cloud+ gem. you can authenticate
|
20
|
+
# using environment variable that uses.
|
21
|
+
def initialize(path: nil, json_string: nil)
|
22
|
+
json_string ||= File.read(path) unless path.nil?
|
23
|
+
json_string = look_for_environment_variables if json_string.nil?
|
24
|
+
|
25
|
+
fail AuthError, "No credentials given." if json_string.nil?
|
26
|
+
@credentials = JSON.parse(json_string)
|
27
|
+
@key = OpenSSL::PKey::RSA.new(@credentials["private_key"])
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] Signed url
|
31
|
+
# Generates signed url.
|
32
|
+
# [bucket] the name of the Cloud Storage bucket that contains the object.
|
33
|
+
# [object_name] the name of the object for signed url..
|
34
|
+
# Variable options are available:
|
35
|
+
# [expires] Time(stamp in UTC) when the signed url expires.
|
36
|
+
# [valid_for] ...or how much seconds is the signed url available.
|
37
|
+
# If you don't set those values, it will set to 300 seconds by default.
|
38
|
+
#
|
39
|
+
# # default is 5 minutes
|
40
|
+
# signer.sign_url("bucket-name", "path/to/file")
|
41
|
+
#
|
42
|
+
# # You can give Time object.
|
43
|
+
# signer.sign_url("bucket-name", "path/to/file",
|
44
|
+
# expires: Time.new(2016, 12, 26, 14, 31, 48, "+09:00"))
|
45
|
+
#
|
46
|
+
# # You can give how much seconds is the signed url valid.
|
47
|
+
# signer.sign_url("bucket", "path/to/file", valid_for: 30 * 60)
|
48
|
+
#
|
49
|
+
# # If you use ActiveSupport, you can also do some magic.
|
50
|
+
# signer.sign_url("bucket", "path/to/file", valid_for: 40.minutes)
|
51
|
+
#
|
52
|
+
# For details information of another options,
|
53
|
+
# like \+method+, \+md5+, and \+content_type+. See:
|
54
|
+
# https://cloud.google.com/storage/docs/access-control/signed-urls
|
55
|
+
#
|
56
|
+
# Just in case if you want to change \+GoogleAccessId+ in the signed url,
|
57
|
+
# You can set \+google_access_id+ as an option.
|
58
|
+
def sign_url(bucket, object_name, options = {})
|
59
|
+
options = apply_default_options(options)
|
60
|
+
|
61
|
+
url = URI.join "https://storage.googleapis.com",
|
62
|
+
URI.escape("/#{bucket}/"), URI.escape(object_name)
|
63
|
+
signature = sign string_that_will_be_signed(url, options)
|
64
|
+
url.query = query_for_signed_url(signature, options)
|
65
|
+
url.to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [String] contains \+project_id+ and \+client_email+
|
69
|
+
# Prevents confidential information (like private key) from exposing
|
70
|
+
# when used with interactive shell such as \+pry+ and \+irb+.
|
71
|
+
def inspect
|
72
|
+
"#<GcsSigner " \
|
73
|
+
"project_id: #{@credentials['project_id']} " \
|
74
|
+
"client_email: #{@credentials['client_email']}>"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Look for environment variable which stores service_account.
|
80
|
+
def look_for_environment_variables
|
81
|
+
unless ENV["GOOGLE_CLOUD_KEYFILE"].nil?
|
82
|
+
return File.read(ENV["GOOGLE_CLOUD_KEYFILE"])
|
83
|
+
end
|
84
|
+
|
85
|
+
ENV["GOOGLE_CLOUD_KEYFILE_JSON"]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Signs the string with the given private key.
|
89
|
+
def sign(string)
|
90
|
+
@key.sign OpenSSL::Digest::SHA256.new, string
|
91
|
+
end
|
92
|
+
|
93
|
+
def apply_default_options(options)
|
94
|
+
{
|
95
|
+
method: "GET", content_md5: nil,
|
96
|
+
content_type: nil,
|
97
|
+
expires: Time.now.utc.to_i + (options[:valid_for] || 300).to_i,
|
98
|
+
google_access_id: @credentials["client_email"]
|
99
|
+
}.merge(options)
|
100
|
+
end
|
101
|
+
|
102
|
+
def string_that_will_be_signed(url, options)
|
103
|
+
[
|
104
|
+
options[:method],
|
105
|
+
options[:content_md5],
|
106
|
+
options[:content_type],
|
107
|
+
options[:expires].to_i,
|
108
|
+
url.path
|
109
|
+
].join "\n"
|
110
|
+
end
|
111
|
+
|
112
|
+
# Escapes and generates query string for actual result.
|
113
|
+
def query_for_signed_url(signature, options)
|
114
|
+
URI.encode_www_form GoogleAccessId: options[:google_access_id],
|
115
|
+
Expires: options[:expires].to_i,
|
116
|
+
Signature: Base64.strict_encode64(signature)
|
117
|
+
end
|
118
|
+
|
119
|
+
# raised When GcsSigner could not find service_account JSON file.
|
120
|
+
class AuthError < StandardError
|
121
|
+
end
|
122
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gcs-signer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sangwon Yi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '12.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '12.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.40.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.40.0
|
55
|
+
description: |2
|
56
|
+
Simple signed URL generator for Google Cloud Storage.
|
57
|
+
No additional gems and API requests required to generate signed URL.
|
58
|
+
email:
|
59
|
+
- sangwon@sha.kr
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- README.md
|
65
|
+
- lib/gcs_signer.rb
|
66
|
+
homepage: https://github.com/shakrmedia/gcs-signer
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - "~>"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '2.2'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.5.2
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Simple signed URL generator for Google Cloud Storage.
|
90
|
+
test_files: []
|