fog-brightbox 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/lib/fog/brightbox.rb +1 -0
  4. data/lib/fog/brightbox/config.rb +102 -2
  5. data/lib/fog/brightbox/core.rb +1 -0
  6. data/lib/fog/brightbox/models/compute/api_client.rb +3 -1
  7. data/lib/fog/brightbox/models/storage/directories.rb +45 -0
  8. data/lib/fog/brightbox/models/storage/directory.rb +53 -0
  9. data/lib/fog/brightbox/models/storage/file.rb +166 -0
  10. data/lib/fog/brightbox/models/storage/files.rb +104 -0
  11. data/lib/fog/brightbox/oauth2.rb +140 -136
  12. data/lib/fog/brightbox/requests/storage/copy_object.rb +27 -0
  13. data/lib/fog/brightbox/requests/storage/delete_container.rb +22 -0
  14. data/lib/fog/brightbox/requests/storage/delete_multiple_objects.rb +67 -0
  15. data/lib/fog/brightbox/requests/storage/delete_object.rb +23 -0
  16. data/lib/fog/brightbox/requests/storage/delete_static_large_object.rb +43 -0
  17. data/lib/fog/brightbox/requests/storage/get_container.rb +44 -0
  18. data/lib/fog/brightbox/requests/storage/get_containers.rb +33 -0
  19. data/lib/fog/brightbox/requests/storage/get_object.rb +29 -0
  20. data/lib/fog/brightbox/requests/storage/get_object_http_url.rb +21 -0
  21. data/lib/fog/brightbox/requests/storage/get_object_https_url.rb +85 -0
  22. data/lib/fog/brightbox/requests/storage/head_container.rb +28 -0
  23. data/lib/fog/brightbox/requests/storage/head_containers.rb +25 -0
  24. data/lib/fog/brightbox/requests/storage/head_object.rb +23 -0
  25. data/lib/fog/brightbox/requests/storage/post_set_meta_temp_url_key.rb +37 -0
  26. data/lib/fog/brightbox/requests/storage/put_container.rb +27 -0
  27. data/lib/fog/brightbox/requests/storage/put_dynamic_obj_manifest.rb +43 -0
  28. data/lib/fog/brightbox/requests/storage/put_object.rb +42 -0
  29. data/lib/fog/brightbox/requests/storage/put_object_manifest.rb +16 -0
  30. data/lib/fog/brightbox/requests/storage/put_static_obj_manifest.rb +57 -0
  31. data/lib/fog/brightbox/storage.rb +166 -0
  32. data/lib/fog/brightbox/storage/authentication_request.rb +52 -0
  33. data/lib/fog/brightbox/storage/config.rb +23 -0
  34. data/lib/fog/brightbox/storage/connection.rb +83 -0
  35. data/lib/fog/brightbox/storage/errors.rb +11 -0
  36. data/lib/fog/brightbox/version.rb +1 -1
  37. data/spec/fog/brightbox/config_spec.rb +62 -1
  38. data/spec/fog/brightbox/storage/authentication_request_spec.rb +77 -0
  39. data/spec/fog/brightbox/storage/config_spec.rb +40 -0
  40. data/spec/fog/brightbox/storage/connection_errors_spec.rb +54 -0
  41. data/spec/fog/brightbox/storage/connection_spec.rb +120 -0
  42. data/spec/fog/storage/brightbox_spec.rb +290 -0
  43. metadata +40 -3
@@ -0,0 +1,104 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/brightbox/models/storage/file'
3
+
4
+ module Fog
5
+ module Storage
6
+ class Brightbox
7
+
8
+ class Files < Fog::Collection
9
+
10
+ attribute :directory
11
+ attribute :limit
12
+ attribute :marker
13
+ attribute :path
14
+ attribute :prefix
15
+
16
+ model Fog::Storage::Brightbox::File
17
+
18
+ def all(options = {})
19
+ requires :directory
20
+ options = {
21
+ 'limit' => limit,
22
+ 'marker' => marker,
23
+ 'path' => path,
24
+ 'prefix' => prefix
25
+ }.merge!(options)
26
+ merge_attributes(options)
27
+ parent = directory.collection.get(
28
+ directory.key,
29
+ options
30
+ )
31
+ if parent
32
+ load(parent.files.map {|file| file.attributes})
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ alias :each_file_this_page :each
39
+ def each
40
+ if !block_given?
41
+ self
42
+ else
43
+ subset = dup.all
44
+
45
+ subset.each_file_this_page {|f| yield f}
46
+ while subset.length == (subset.limit || 10000)
47
+ subset = subset.all(:marker => subset.last.key)
48
+ subset.each_file_this_page {|f| yield f}
49
+ end
50
+
51
+ self
52
+ end
53
+ end
54
+
55
+ def get(key, &block)
56
+ requires :directory
57
+ data = service.get_object(directory.key, key, &block)
58
+ file_data = data.headers.merge({
59
+ :body => data.body,
60
+ :key => key
61
+ })
62
+ new(file_data)
63
+ rescue Fog::Storage::Brightbox::NotFound
64
+ nil
65
+ end
66
+
67
+ def get_url(key)
68
+ requires :directory
69
+ if self.directory.public_url
70
+ "#{self.directory.public_url}/#{Fog::Storage::Brightbox.escape(key, '/')}"
71
+ end
72
+ end
73
+
74
+ def get_http_url(key, expires, options = {})
75
+ requires :directory
76
+ service.get_object_http_url(directory.key, key, expires, options)
77
+ end
78
+
79
+ def get_https_url(key, expires, options = {})
80
+ requires :directory
81
+ service.get_object_https_url(directory.key, key, expires, options)
82
+ end
83
+
84
+ def head(key, options = {})
85
+ requires :directory
86
+ data = service.head_object(directory.key, key)
87
+ file_data = data.headers.merge({
88
+ :key => key
89
+ })
90
+ new(file_data)
91
+ rescue Fog::Storage::Brightbox::NotFound
92
+ nil
93
+ end
94
+
95
+ def new(attributes = {})
96
+ requires :directory
97
+ super({ :directory => directory }.merge!(attributes))
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+ end
104
+ end
@@ -3,164 +3,168 @@
3
3
  #
4
4
  # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10
5
5
  #
6
- module Fog::Brightbox::OAuth2
7
-
8
- # This builds the simplest form of requesting an access token
9
- # based on the arguments passed in
10
- #
11
- # @param [Fog::Core::Connection] connection
12
- # @param [CredentialSet] credentials
13
- #
14
- # @return [Excon::Response]
15
- def request_access_token(connection, credentials)
16
- token_strategy = credentials.best_grant_strategy
17
-
18
- header_content = "#{credentials.client_id}:#{credentials.client_secret}"
19
- encoded_credentials = Base64.encode64(header_content).chomp
20
-
21
- connection.request(
22
- :path => "/token",
23
- :expects => 200,
24
- :headers => {
25
- 'Authorization' => "Basic #{encoded_credentials}",
26
- 'Content-Type' => 'application/json'
27
- },
28
- :method => 'POST',
29
- :body => Fog::JSON.encode(token_strategy.authorization_body_data)
30
- )
31
- end
6
+ module Fog
7
+ module Brightbox
8
+ module OAuth2
32
9
 
33
- # Encapsulates credentials required to request access tokens from the
34
- # Brightbox authorisation servers
35
- #
36
- # @todo Interface to update certain credentials (after password change)
37
- #
38
- class CredentialSet
39
- attr_reader :client_id, :client_secret, :username, :password
40
- attr_reader :access_token, :refresh_token, :expires_in
10
+ # This builds the simplest form of requesting an access token
11
+ # based on the arguments passed in
41
12
  #
42
- # @param [String] client_id
43
- # @param [String] client_secret
44
- # @param [Hash] options
45
- # @option options [String] :username
46
- # @option options [String] :password
13
+ # @param [Fog::Core::Connection] connection
14
+ # @param [CredentialSet] credentials
47
15
  #
48
- def initialize(client_id, client_secret, options = {})
49
- @client_id = client_id
50
- @client_secret = client_secret
51
- @username = options[:username]
52
- @password = options[:password]
53
- @access_token = options[:access_token]
54
- @refresh_token = options[:refresh_token]
55
- @expires_in = options[:expires_in]
16
+ # @return [Excon::Response]
17
+ def request_access_token(connection, credentials)
18
+ token_strategy = credentials.best_grant_strategy
19
+
20
+ header_content = "#{credentials.client_id}:#{credentials.client_secret}"
21
+ encoded_credentials = Base64.encode64(header_content).chomp
22
+
23
+ connection.request(
24
+ :path => "/token",
25
+ :expects => 200,
26
+ :headers => {
27
+ 'Authorization' => "Basic #{encoded_credentials}",
28
+ 'Content-Type' => 'application/json'
29
+ },
30
+ :method => 'POST',
31
+ :body => Fog::JSON.encode(token_strategy.authorization_body_data)
32
+ )
56
33
  end
57
34
 
58
- # Returns true if user details are available
59
- # @return [Boolean]
60
- def user_details?
61
- !!(@username && @password)
62
- end
35
+ # Encapsulates credentials required to request access tokens from the
36
+ # Brightbox authorisation servers
37
+ #
38
+ # @todo Interface to update certain credentials (after password change)
39
+ #
40
+ class CredentialSet
41
+ attr_reader :client_id, :client_secret, :username, :password
42
+ attr_reader :access_token, :refresh_token, :expires_in
43
+ #
44
+ # @param [String] client_id
45
+ # @param [String] client_secret
46
+ # @param [Hash] options
47
+ # @option options [String] :username
48
+ # @option options [String] :password
49
+ #
50
+ def initialize(client_id, client_secret, options = {})
51
+ @client_id = client_id
52
+ @client_secret = client_secret
53
+ @username = options[:username]
54
+ @password = options[:password]
55
+ @access_token = options[:access_token]
56
+ @refresh_token = options[:refresh_token]
57
+ @expires_in = options[:expires_in]
58
+ end
63
59
 
64
- # Is an access token available for these credentials?
65
- def access_token?
66
- !!@access_token
67
- end
60
+ # Returns true if user details are available
61
+ # @return [Boolean]
62
+ def user_details?
63
+ !!(@username && @password)
64
+ end
68
65
 
69
- # Is a refresh token available for these credentials?
70
- def refresh_token?
71
- !!@refresh_token
72
- end
66
+ # Is an access token available for these credentials?
67
+ def access_token?
68
+ !!@access_token
69
+ end
73
70
 
74
- # Updates the credentials with newer tokens
75
- def update_tokens(access_token, refresh_token = nil, expires_in = nil)
76
- @access_token = access_token
77
- @refresh_token = refresh_token
78
- @expires_in = expires_in
71
+ # Is a refresh token available for these credentials?
72
+ def refresh_token?
73
+ !!@refresh_token
74
+ end
75
+
76
+ # Updates the credentials with newer tokens
77
+ def update_tokens(access_token, refresh_token = nil, expires_in = nil)
78
+ @access_token = access_token
79
+ @refresh_token = refresh_token
80
+ @expires_in = expires_in
81
+ end
82
+
83
+ # Based on available credentials returns the best strategy
84
+ #
85
+ # @todo Add a means to dictate which should or shouldn't be used
86
+ #
87
+ def best_grant_strategy
88
+ if refresh_token?
89
+ RefreshTokenStrategy.new(self)
90
+ elsif user_details?
91
+ UserCredentialsStrategy.new(self)
92
+ else
93
+ ClientCredentialsStrategy.new(self)
94
+ end
95
+ end
79
96
  end
80
97
 
81
- # Based on available credentials returns the best strategy
98
+ # This strategy class is the basis for OAuth2 grant types
99
+ #
100
+ # @abstract Need to implement {#authorization_body_data} to return a
101
+ # Hash matching the expected parameter form for the OAuth request
82
102
  #
83
- # @todo Add a means to dictate which should or shouldn't be used
103
+ # @todo Strategies should be able to validate if credentials are suitable
104
+ # so just client credentials cannot be used with user strategies
84
105
  #
85
- def best_grant_strategy
86
- if refresh_token?
87
- RefreshTokenStrategy.new(self)
88
- elsif user_details?
89
- UserCredentialsStrategy.new(self)
90
- else
91
- ClientCredentialsStrategy.new(self)
106
+ class GrantTypeStrategy
107
+ def initialize(credentials)
108
+ @credentials = credentials
92
109
  end
93
- end
94
- end
95
110
 
96
- # This strategy class is the basis for OAuth2 grant types
97
- #
98
- # @abstract Need to implement {#authorization_body_data} to return a
99
- # Hash matching the expected parameter form for the OAuth request
100
- #
101
- # @todo Strategies should be able to validate if credentials are suitable
102
- # so just client credentials cannot be used with user strategies
103
- #
104
- class GrantTypeStrategy
105
- def initialize(credentials)
106
- @credentials = credentials
111
+ def authorization_body_data
112
+ raise "Not implemented"
113
+ end
107
114
  end
108
115
 
109
- def authorization_body_data
110
- raise "Not implemented"
116
+ # This implements client based authentication/authorization
117
+ # based on the existing trust relationship using the `none`
118
+ # grant type.
119
+ #
120
+ class ClientCredentialsStrategy < GrantTypeStrategy
121
+ def authorization_body_data
122
+ {
123
+ "grant_type" => "none",
124
+ "client_id" => @credentials.client_id
125
+ }
126
+ end
111
127
  end
112
- end
113
128
 
114
- # This implements client based authentication/authorization
115
- # based on the existing trust relationship using the `none`
116
- # grant type.
117
- #
118
- class ClientCredentialsStrategy < GrantTypeStrategy
119
- def authorization_body_data
120
- {
121
- "grant_type" => "none",
122
- "client_id" => @credentials.client_id
123
- }
129
+ # This passes user details through so the returned token
130
+ # carries the privileges of the user not account limited
131
+ # by the client
132
+ #
133
+ class UserCredentialsStrategy < GrantTypeStrategy
134
+ def authorization_body_data
135
+ {
136
+ "grant_type" => "password",
137
+ "client_id" => @credentials.client_id,
138
+ "username" => @credentials.username,
139
+ "password" => @credentials.password
140
+ }
141
+ end
124
142
  end
125
- end
126
143
 
127
- # This passes user details through so the returned token
128
- # carries the privileges of the user not account limited
129
- # by the client
130
- #
131
- class UserCredentialsStrategy < GrantTypeStrategy
132
- def authorization_body_data
133
- {
134
- "grant_type" => "password",
135
- "client_id" => @credentials.client_id,
136
- "username" => @credentials.username,
137
- "password" => @credentials.password
138
- }
139
- end
140
- end
141
-
142
- # This strategy attempts to use a refresh_token gained during an earlier
143
- # request to reuse the credentials given originally
144
- #
145
- class RefreshTokenStrategy < GrantTypeStrategy
146
- def authorization_body_data
147
- {
148
- "grant_type" => "refresh_token",
149
- "client_id" => @credentials.client_id,
150
- "refresh_token" => @credentials.refresh_token
151
- }
144
+ # This strategy attempts to use a refresh_token gained during an earlier
145
+ # request to reuse the credentials given originally
146
+ #
147
+ class RefreshTokenStrategy < GrantTypeStrategy
148
+ def authorization_body_data
149
+ {
150
+ "grant_type" => "refresh_token",
151
+ "client_id" => @credentials.client_id,
152
+ "refresh_token" => @credentials.refresh_token
153
+ }
154
+ end
152
155
  end
153
- end
154
156
 
155
- private
157
+ private
156
158
 
157
- # This updates the current credentials if passed a valid response
158
- #
159
- # @param [CredentialSet] credentials Credentials to update
160
- # @param [Excon::Response] response Response object to parse value from
161
- #
162
- def update_credentials_from_response(credentials, response)
163
- response_data = Fog::JSON.decode(response.body)
164
- credentials.update_tokens(response_data["access_token"], response_data["refresh_token"], response_data["expires_in"])
159
+ # This updates the current credentials if passed a valid response
160
+ #
161
+ # @param [CredentialSet] credentials Credentials to update
162
+ # @param [Excon::Response] response Response object to parse value from
163
+ #
164
+ def update_credentials_from_response(credentials, response)
165
+ response_data = Fog::JSON.decode(response.body)
166
+ credentials.update_tokens(response_data["access_token"], response_data["refresh_token"], response_data["expires_in"])
167
+ end
165
168
  end
166
169
  end
170
+ end
@@ -0,0 +1,27 @@
1
+ module Fog
2
+ module Storage
3
+ class Brightbox
4
+ class Real
5
+
6
+ # Copy object
7
+ #
8
+ # ==== Parameters
9
+ # * source_container_name<~String> - Name of source bucket
10
+ # * source_object_name<~String> - Name of source object
11
+ # * target_container_name<~String> - Name of bucket to create copy in
12
+ # * target_object_name<~String> - Name for new copy of object
13
+ # * options<~Hash> - Additional headers
14
+ def copy_object(source_container_name, source_object_name, target_container_name, target_object_name, options={})
15
+ headers = { 'X-Copy-From' => "/#{source_container_name}/#{source_object_name}" }.merge(options)
16
+ request({
17
+ :expects => 201,
18
+ :headers => headers,
19
+ :method => 'PUT',
20
+ :path => "#{Fog::Storage::Brightbox.escape(target_container_name)}/#{Fog::Storage::Brightbox.escape(target_object_name)}"
21
+ })
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module Fog
2
+ module Storage
3
+ class Brightbox
4
+ class Real
5
+
6
+ # Delete an existing container
7
+ #
8
+ # ==== Parameters
9
+ # * name<~String> - Name of container to delete
10
+ #
11
+ def delete_container(name)
12
+ request(
13
+ :expects => 204,
14
+ :method => 'DELETE',
15
+ :path => Fog::Storage::Brightbox.escape(name)
16
+ )
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end