assembla_api 0.1.2

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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/Rakefile +22 -0
  4. data/lib/assembla_api.rb +130 -0
  5. data/lib/assembla_api/api.rb +373 -0
  6. data/lib/assembla_api/api/actions.rb +58 -0
  7. data/lib/assembla_api/api/arguments.rb +248 -0
  8. data/lib/assembla_api/api/config.rb +107 -0
  9. data/lib/assembla_api/api/config/property.rb +30 -0
  10. data/lib/assembla_api/api/config/property_set.rb +119 -0
  11. data/lib/assembla_api/api/factory.rb +33 -0
  12. data/lib/assembla_api/authorization.rb +76 -0
  13. data/lib/assembla_api/client.rb +21 -0
  14. data/lib/assembla_api/client/activity.rb +30 -0
  15. data/lib/assembla_api/client/authorizations.rb +143 -0
  16. data/lib/assembla_api/client/authorizations/app.rb +98 -0
  17. data/lib/assembla_api/client/portfolio.rb +19 -0
  18. data/lib/assembla_api/client/portfolio/invitations.rb +30 -0
  19. data/lib/assembla_api/client/portfolio/spaces.rb +13 -0
  20. data/lib/assembla_api/client/portfolio/standup_reports.rb +34 -0
  21. data/lib/assembla_api/client/portfolio/tasks.rb +13 -0
  22. data/lib/assembla_api/client/portfolio/ticket_reports.rb +13 -0
  23. data/lib/assembla_api/client/portfolio/tickets.rb +13 -0
  24. data/lib/assembla_api/client/portfolio/users.rb +13 -0
  25. data/lib/assembla_api/client/spaces.rb +140 -0
  26. data/lib/assembla_api/client/spaces/documents.rb +87 -0
  27. data/lib/assembla_api/client/spaces/milestones.rb +102 -0
  28. data/lib/assembla_api/client/spaces/space_tools.rb +65 -0
  29. data/lib/assembla_api/client/spaces/space_tools/merge_requests.rb +105 -0
  30. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions.rb +41 -0
  31. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/comments.rb +34 -0
  32. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/votes.rb +46 -0
  33. data/lib/assembla_api/client/spaces/ssh.rb +14 -0
  34. data/lib/assembla_api/client/spaces/ssh/actions.rb +76 -0
  35. data/lib/assembla_api/client/spaces/ssh/actions/launches.rb +14 -0
  36. data/lib/assembla_api/client/spaces/ssh/keys.rb +18 -0
  37. data/lib/assembla_api/client/spaces/ssh/launches.rb +29 -0
  38. data/lib/assembla_api/client/spaces/ssh/servers.rb +63 -0
  39. data/lib/assembla_api/client/spaces/standup_away_reports.rb +41 -0
  40. data/lib/assembla_api/client/spaces/standup_reports.rb +41 -0
  41. data/lib/assembla_api/client/spaces/tags.rb +96 -0
  42. data/lib/assembla_api/client/spaces/tickets.rb +154 -0
  43. data/lib/assembla_api/client/spaces/tickets/associations.rb +57 -0
  44. data/lib/assembla_api/client/spaces/tickets/comments.rb +45 -0
  45. data/lib/assembla_api/client/spaces/tickets/custom_fields.rb +57 -0
  46. data/lib/assembla_api/client/spaces/tickets/statuses.rb +55 -0
  47. data/lib/assembla_api/client/spaces/user_roles.rb +61 -0
  48. data/lib/assembla_api/client/spaces/users.rb +11 -0
  49. data/lib/assembla_api/client/spaces/webhooks.rb +63 -0
  50. data/lib/assembla_api/client/spaces/wiki_pages.rb +78 -0
  51. data/lib/assembla_api/client/spaces/wiki_pages/versions.rb +20 -0
  52. data/lib/assembla_api/client/tasks.rb +72 -0
  53. data/lib/assembla_api/client/users.rb +49 -0
  54. data/lib/assembla_api/client/users/keys.rb +97 -0
  55. data/lib/assembla_api/configuration.rb +71 -0
  56. data/lib/assembla_api/connection.rb +66 -0
  57. data/lib/assembla_api/constants.rb +74 -0
  58. data/lib/assembla_api/core_ext/array.rb +25 -0
  59. data/lib/assembla_api/core_ext/hash.rb +92 -0
  60. data/lib/assembla_api/core_ext/ordered_hash.rb +107 -0
  61. data/lib/assembla_api/deprecation.rb +39 -0
  62. data/lib/assembla_api/error.rb +37 -0
  63. data/lib/assembla_api/error/bad_request.rb +14 -0
  64. data/lib/assembla_api/error/client_error.rb +20 -0
  65. data/lib/assembla_api/error/forbidden.rb +14 -0
  66. data/lib/assembla_api/error/internal_server_error.rb +15 -0
  67. data/lib/assembla_api/error/invalid_options.rb +18 -0
  68. data/lib/assembla_api/error/not_acceptable.rb +15 -0
  69. data/lib/assembla_api/error/not_found.rb +14 -0
  70. data/lib/assembla_api/error/required_params.rb +18 -0
  71. data/lib/assembla_api/error/service_error.rb +68 -0
  72. data/lib/assembla_api/error/service_unavailable.rb +15 -0
  73. data/lib/assembla_api/error/unauthorized.rb +15 -0
  74. data/lib/assembla_api/error/unknown_media.rb +18 -0
  75. data/lib/assembla_api/error/unknown_value.rb +18 -0
  76. data/lib/assembla_api/error/unprocessable_entity.rb +14 -0
  77. data/lib/assembla_api/error/validations.rb +18 -0
  78. data/lib/assembla_api/ext/faraday.rb +38 -0
  79. data/lib/assembla_api/jsonable.rb +18 -0
  80. data/lib/assembla_api/middleware.rb +31 -0
  81. data/lib/assembla_api/mime_type.rb +33 -0
  82. data/lib/assembla_api/normalizer.rb +25 -0
  83. data/lib/assembla_api/null_encoder.rb +25 -0
  84. data/lib/assembla_api/page_iterator.rb +142 -0
  85. data/lib/assembla_api/page_links.rb +45 -0
  86. data/lib/assembla_api/paged_request.rb +40 -0
  87. data/lib/assembla_api/pagination.rb +102 -0
  88. data/lib/assembla_api/parameter_filter.rb +32 -0
  89. data/lib/assembla_api/params_hash.rb +101 -0
  90. data/lib/assembla_api/rate_limit.rb +25 -0
  91. data/lib/assembla_api/request.rb +85 -0
  92. data/lib/assembla_api/request/basic_auth.rb +33 -0
  93. data/lib/assembla_api/request/jsonize.rb +53 -0
  94. data/lib/assembla_api/request/key_auth.rb +31 -0
  95. data/lib/assembla_api/request/oauth2.rb +42 -0
  96. data/lib/assembla_api/request/verbs.rb +60 -0
  97. data/lib/assembla_api/response.rb +28 -0
  98. data/lib/assembla_api/response/header.rb +76 -0
  99. data/lib/assembla_api/response/jsonize.rb +29 -0
  100. data/lib/assembla_api/response/mashify.rb +24 -0
  101. data/lib/assembla_api/response/raise_error.rb +18 -0
  102. data/lib/assembla_api/response/xmlize.rb +26 -0
  103. data/lib/assembla_api/response_wrapper.rb +157 -0
  104. data/lib/assembla_api/ssl_certs/cacerts.pem +2183 -0
  105. data/lib/assembla_api/utils/url.rb +59 -0
  106. data/lib/assembla_api/validations.rb +25 -0
  107. data/lib/assembla_api/validations/format.rb +24 -0
  108. data/lib/assembla_api/validations/presence.rb +30 -0
  109. data/lib/assembla_api/validations/required.rb +24 -0
  110. data/lib/assembla_api/validations/token.rb +41 -0
  111. data/lib/assembla_api/version.rb +12 -0
  112. metadata +347 -0
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require 'assembla_api/core_ext/hash'
4
+
5
+ module Assembla
6
+ class API
7
+ class Factory
8
+
9
+ # Instantiates a new assembla api object
10
+ #
11
+ def self.new(klass, options={}, &block)
12
+ return create_instance(klass, options, &block) if klass
13
+ raise ArgumentError, 'must provide API class to be instantiated'
14
+ end
15
+
16
+ # Passes configuration options to instantiated class
17
+ #
18
+ def self.create_instance(klass, options, &block)
19
+ options.symbolize_keys!
20
+ convert_to_constant(klass.to_s).new options, &block
21
+ end
22
+
23
+ # Convert name to constant
24
+ #
25
+ def self.convert_to_constant(classes)
26
+ classes.split('::').inject(Assembla) do |constant, klass|
27
+ constant.const_get klass
28
+ end
29
+ end
30
+
31
+ end # Factory
32
+ end # Api
33
+ end # Assembla
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ module Authorization
5
+
6
+ attr_accessor :scopes
7
+
8
+ # Setup OAuth2 instance
9
+ def client
10
+ @client ||= ::OAuth2::Client.new(client_id, client_secret,
11
+ {
12
+ :site => current_options.fetch(:site) { Assembla.site },
13
+ :authorize_url => 'authorization',
14
+ :token_url => 'token',
15
+ :ssl => { :verify => false }
16
+ }
17
+ )
18
+ end
19
+
20
+ # Strategy token
21
+ def auth_code
22
+ _verify_client
23
+ client.auth_code
24
+ end
25
+
26
+ # Sends authorization request to Assembla.
27
+ # = Parameters
28
+ # * <tt>:redirect_uri</tt> - Optional string.
29
+ # * <tt>:scope</tt> - Optional string. Comma separated list of scopes.
30
+ # Available scopes:
31
+ # * (no scope) - public read-only access (includes public user profile info, public repo info, and gists).
32
+ # * <tt>user</tt> - DB read/write access to profile info only.
33
+ # * <tt>public_repo</tt> - DB read/write access, and Git read access to public repos.
34
+ # * <tt>repo</tt> - DB read/write access, and Git read access to public and private repos.
35
+ # * <tt>gist</tt> - write access to gists.
36
+ #
37
+ def authorize_url(params = {})
38
+ _verify_client
39
+ client.auth_code.authorize_url(params)
40
+ end
41
+
42
+ # Makes request to token endpoint and retrieves access token value
43
+ def get_token(authorization_code, params = {})
44
+ _verify_client
45
+ client.auth_code.get_token(authorization_code, params)
46
+ end
47
+
48
+ # Check whether authentication credentials are present
49
+ def authenticated?
50
+ basic_authed? || oauth_token?
51
+ end
52
+
53
+ # Check whether basic authentication credentials are present
54
+ def basic_authed?
55
+ basic_auth? || (login? && password?)
56
+ end
57
+
58
+ # Select authentication parameters
59
+ def authentication
60
+ if basic_auth?
61
+ { :basic_auth => basic_auth }
62
+ elsif login? && password?
63
+ { :login => login, :password => password }
64
+ else
65
+ { }
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def _verify_client # :nodoc:
72
+ raise ArgumentError, 'Need to provide client_id and client_secret' unless client_id? && client_secret?
73
+ end
74
+
75
+ end # Authorization
76
+ end # Assembla
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ class Client < API
5
+
6
+ require_all 'assembla_api/client',
7
+ 'portfolio',
8
+ 'activity',
9
+ 'spaces',
10
+ 'tasks',
11
+ 'users'
12
+
13
+ namespace :activity
14
+ namespace :spaces
15
+ namespace :portfolio
16
+
17
+ # Many of the resources on the users API provide a shortcut for getting
18
+ # information about the currently authenticated user.
19
+ namespace :users
20
+ end # Client
21
+ end # Assembla
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ class Client::Activity < API
5
+ VALID_REQUEST_PARAM_NAMES = %w[
6
+ space_id
7
+ to
8
+ from
9
+ ].freeze
10
+
11
+ TIME_REGEXP = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/
12
+
13
+ VALID_REQUEST_PARAM_VALUES = {
14
+ 'to' => TIME_REGEXP,
15
+ 'from' => TIME_REGEXP
16
+ }
17
+
18
+ def list(*args)
19
+ arguments(args) do
20
+ permit VALID_REQUEST_PARAM_NAMES
21
+ assert_values VALID_REQUEST_PARAM_VALUES
22
+ end
23
+
24
+ response = get_request("/activity", arguments.params)
25
+ return response unless block_given?
26
+ response.each { |el| yield el }
27
+ end
28
+
29
+ end # Activity
30
+ end # Assembla
@@ -0,0 +1,143 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ # OAuth Authorizations API
5
+ class Client::Authorizations < API
6
+
7
+ require_all 'assembla_api/client/authorizations', 'app'
8
+
9
+ VALID_AUTH_PARAM_NAMES = %w[
10
+ scopes
11
+ add_scopes
12
+ remove_scopes
13
+ note
14
+ note_url
15
+ client_id
16
+ client_secret
17
+ ].freeze
18
+
19
+ # Access to Authorizations::App API
20
+ namespace :app
21
+
22
+ # List authorizations
23
+ #
24
+ # @see https://developer.assembla.com/v3/oauth_authorizations/#list-your-authorizations
25
+ #
26
+ # @example
27
+ # assembla = Assembla.new basic_auth: 'login:password'
28
+ # assembla.oauth.list
29
+ # assembla.oauth.list { |auth| ... }
30
+ #
31
+ # @api public
32
+ def list(*args)
33
+ raise_authentication_error unless authenticated?
34
+ arguments(args)
35
+
36
+ response = get_request('/authorizations', arguments.params)
37
+ return response unless block_given?
38
+ response.each { |el| yield el }
39
+ end
40
+ alias :all :list
41
+
42
+ # Get a single authorization
43
+ #
44
+ # @see https://developer.assembla.com/v3/oauth_authorizations/#get-a-single-authorization
45
+ #
46
+ # @example
47
+ # assembla = Assembla.new basic_auth: 'login:password'
48
+ # assembla.oauth.get 'authorization-id'
49
+ #
50
+ # @return [ResponseWrapper]
51
+ #
52
+ # @api public
53
+ def get(*args)
54
+ raise_authentication_error unless authenticated?
55
+ arguments(args, required: [:id])
56
+
57
+ get_request("/authorizations/#{arguments.id}", arguments.params)
58
+ end
59
+ alias :find :get
60
+
61
+ # Create a new authorization
62
+ #
63
+ # @param [Hash] params
64
+ # @option params [Array[String]] :scopes
65
+ # A list of scopes that this authorization is in.
66
+ # @option params [String] :note
67
+ # A note to remind you what the OAuth token is for.
68
+ # @option params [String] :note_url
69
+ # A URL to remind you what the OAuth token is for.
70
+ # @option params [String] :client_id
71
+ # The 20 character OAuth app client key for which to create the token.
72
+ # @option params [String] :client_secret
73
+ # The 40 character OAuth app client secret for which to create the token.
74
+ #
75
+ # @example
76
+ # assembla = Assembla.new basic_auth: 'login:password'
77
+ # assembla.oauth.create
78
+ # "scopes" => ["public_repo"]
79
+ #
80
+ # @api public
81
+ def create(*args)
82
+ raise_authentication_error unless authenticated?
83
+ arguments(args) do
84
+ permit VALID_AUTH_PARAM_NAMES
85
+ end
86
+
87
+ post_request('/authorizations', arguments.params)
88
+ end
89
+
90
+ # Update an existing authorization
91
+ #
92
+ # @param [Hash] inputs
93
+ # @option inputs [Array] :scopes
94
+ # Optional array - A list of scopes that this authorization is in.
95
+ # @option inputs [Array] :add_scopes
96
+ # Optional array - A list of scopes to add to this authorization.
97
+ # @option inputs [Array] :remove_scopes
98
+ # Optional array - A list of scopes to remove from this authorization.
99
+ # @option inputs [String] :note
100
+ # Optional string - A note to remind you what the OAuth token is for.
101
+ # @optoin inputs [String] :note_url
102
+ # Optional string - A URL to remind you what the OAuth token is for.
103
+ #
104
+ # @example
105
+ # assembla = Assembla.new basic_auth: 'login:password'
106
+ # assembla.oauth.update "authorization-id", add_scopes: ["repo"]
107
+ #
108
+ # @api public
109
+ def update(*args)
110
+ raise_authentication_error unless authenticated?
111
+ arguments(args, required: [:id]) do
112
+ permit VALID_AUTH_PARAM_NAMES
113
+ end
114
+
115
+ patch_request("/authorizations/#{arguments.id}", arguments.params)
116
+ end
117
+ alias :edit :update
118
+
119
+ # Delete an authorization
120
+ #
121
+ # @see https://developer.assembla.com/v3/oauth_authorizations/#delete-an-authorization
122
+ #
123
+ # @example
124
+ # assembla.oauth.delete 'authorization-id'
125
+ #
126
+ # @api public
127
+ def delete(*args)
128
+ raise_authentication_error unless authenticated?
129
+ arguments(args, required: [:id])
130
+
131
+ delete_request("/authorizations/#{arguments.id}", arguments.params)
132
+ end
133
+ alias :remove :delete
134
+
135
+ protected
136
+
137
+ def raise_authentication_error
138
+ raise ArgumentError, 'You can only access your own tokens' +
139
+ ' via Basic Authentication'
140
+ end
141
+
142
+ end # Client::Authorizations
143
+ end # Assembla
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ class Client::Authorizations::App < Client::Authorizations
5
+ # Get-or-create an authorization for a specific app
6
+ #
7
+ # @see https://developer.assembla.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
8
+ #
9
+ # @param [Hash] params
10
+ # @option params [String] client_secret
11
+ # The 40 character OAuth app client secret associated with the client
12
+ # ID specified in the URL.
13
+ # @option params [Array] :scopes
14
+ # Optional array - A list of scopes that this authorization is in.
15
+ # @option params [String] :note
16
+ # Optional string - A note to remind you what the OAuth token is for.
17
+ # @option params [String] :note_url
18
+ # Optional string - A URL to remind you what the OAuth token is for.
19
+ #
20
+ # @example
21
+ # assembla = Assembla.new
22
+ # assembla.oauth.app.create 'client-id', client_secret: '...'
23
+ #
24
+ # @api public
25
+ def create(*args)
26
+ raise_authentication_error unless authenticated?
27
+ arguments(args, required: [:client_id]) do
28
+ permit VALID_AUTH_PARAM_NAMES
29
+ end
30
+
31
+ if arguments.client_id
32
+ put_request("/authorizations/clients/#{arguments.client_id}", arguments.params)
33
+ else
34
+ raise raise_app_authentication_error
35
+ end
36
+ end
37
+
38
+ # Check if an access token is a valid authorization for an application
39
+ #
40
+ # @example
41
+ # assembla = Assembla.new basic_auth: "client_id:client_secret"
42
+ # assembla.oauth.app.check 'client_id', 'access-token'
43
+ #
44
+ # @api public
45
+ def check(*args)
46
+ raise_authentication_error unless authenticated?
47
+ params = arguments(args, required: [:client_id, :access_token]).params
48
+
49
+ if arguments.client_id
50
+ begin
51
+ get_request("/applications/#{arguments.client_id}/tokens/#{arguments.access_token}", params)
52
+ rescue Assembla::Error::NotFound => e
53
+ nil
54
+ end
55
+ else
56
+ raise raise_app_authentication_error
57
+ end
58
+ end
59
+
60
+ # Revoke all authorizations for an application
61
+ #
62
+ # @example
63
+ # assembla = Assembla.new basic_auth: "client_id:client_secret"
64
+ # assembla.oauth.app.delete 'client-id'
65
+ #
66
+ # Revoke an authorization for an application
67
+ #
68
+ # @example
69
+ # assembla = Assembla.new basic_auth: "client_id:client_secret"
70
+ # assembla.oauth.app.delete 'client-id', 'access-token'
71
+ #
72
+ # @api public
73
+ def delete(*args)
74
+ raise_authentication_error unless authenticated?
75
+ params = arguments(args, required: [:client_id]).params
76
+
77
+ if arguments.client_id
78
+ if access_token = (params.delete('access_token') || args[1])
79
+ delete_request("/applications/#{arguments.client_id}/tokens/#{access_token}", params)
80
+ else
81
+ # Revokes all tokens
82
+ delete_request("/applications/#{arguments.client_id}/tokens", params)
83
+ end
84
+ else
85
+ raise raise_app_authentication_error
86
+ end
87
+ end
88
+ alias :remove :delete
89
+ alias :revoke :delete
90
+
91
+ protected
92
+
93
+ def raise_app_authentication_error
94
+ raise ArgumentError, 'To create authorization for the app, ' +
95
+ 'you need to provide client_id argument and client_secret parameter'
96
+ end
97
+ end # Client::Authorizations::App
98
+ end # Assembla
@@ -0,0 +1,19 @@
1
+ module Assembla
2
+ class Client::Portfolio < API
3
+ require_all 'assembla_api/client/portfolio',
4
+ 'tasks',
5
+ 'users',
6
+ 'tickets',
7
+ 'spaces',
8
+ 'ticket_reports',
9
+ 'standup_reports',
10
+ 'invitations'
11
+
12
+ namespace :tasks
13
+ namespace :users
14
+ namespace :tickets
15
+ namespace :ticket_reports
16
+ namespace :standup_reports
17
+ namespace :invitations
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ module Assembla
2
+ class Client::Portfolio::Invitations < API
3
+
4
+ # @example
5
+ # api.portfolio.invitations.list
6
+ def list(*args)
7
+ arguments(args)
8
+ response = get_request("/invitations", arguments.params)
9
+ return response unless block_given?
10
+ response.each { |el| yield el }
11
+ end
12
+
13
+ # @example
14
+ # api.portfolio.invitations.create
15
+ def create(*args)
16
+ arguments(args) do
17
+ permit %w{ role title identifiers }, recursive: true
18
+ end
19
+
20
+ post_request("/invitations", arguments.params)
21
+ end
22
+
23
+ # @example
24
+ # api.portfolio.invitations.get 187
25
+ def get(*args)
26
+ arguments(args, required: [:id])
27
+ get_request("/invitations/#{arguments.id}", arguments.params)
28
+ end
29
+ end
30
+ end