conjur-api 4.19.1 → 4.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
2
+ # Copyright (C) 2013-2015 Conjur Inc
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
5
  # this software and associated documentation files (the "Software"), to deal in
@@ -19,6 +19,7 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  require 'conjur/user'
22
+ require 'conjur/cidr'
22
23
 
23
24
  module Conjur
24
25
  class API
@@ -48,12 +49,16 @@ module Conjur
48
49
  # @param [String] login the login for the new user
49
50
  # @param [Hash] options options for user creation
50
51
  # @option options [String] :acting_as Qualified id of a role to perform the action as
52
+ # @option options [Array<String, IPAddr>] :cidr CIDR addresses of networks
53
+ # the new user will be allower to login from
51
54
  # @option options [String, Integer] :uidnumber UID number to assign to the new user. If not given, one will be generated.
52
55
  # @option options [String] :password when present, the user will be given a password in addition to a randomly
53
56
  # generated api key.
54
57
  # @return [Conjur::User] an object representing the new user
55
58
  # @raise [RestClient::Conflict] If the user already exists, or a user with the given uidnumber exists.
56
59
  def create_user(login, options = {})
60
+ options = options.merge \
61
+ cidr: [*options[:cidr]].map(&CIDR.method(:validate)).map(&:to_s) if options[:cidr]
57
62
  standard_create Conjur::Core::API.host, :user, nil, options.merge(login: login)
58
63
  end
59
64
 
@@ -105,6 +105,30 @@ module Conjur
105
105
  end
106
106
  end
107
107
 
108
+ # Fetch all visible variables that expire within the given
109
+ # interval (relative to the current time on the Conjur Server). If
110
+ # no interval is specifed, all variables that are set to expire
111
+ # will be returned.
112
+ #
113
+ # interval should either be a String containing an ISO8601
114
+ # duration, or it should implement #to_i to return a number of
115
+ # seconds.
116
+ #
117
+ # @example Use an ISO8601 duration to return variables expiring in the next month
118
+ # expirations = api.variable_expirations('P1M')
119
+ #
120
+ # @example Use ActiveSupport to return variables expiring in the next month
121
+ # require 'active_support/all'
122
+ # expirations = api.variable_expirations(1.month)
123
+
124
+ # param interval a String containing an ISO8601 duration , or a number of seconds
125
+ # return [Hash] variable expirations that occur within the interval
126
+ def variable_expirations(interval = nil)
127
+ duration = interval.try { |i| i.respond_to?(:to_str) ? i : "PT#{i.to_i}S" }
128
+ params = {}.tap { |p| p.merge!({:params => {:duration => duration }}) if duration }
129
+ JSON.parse(RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/expirations'].get(params).body)
130
+ end
131
+
108
132
  #@!endgroup
109
133
  end
110
134
  end
@@ -0,0 +1,71 @@
1
+ #
2
+ # Copyright (C) 2015 Conjur Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ ##
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+
22
+ require 'ipaddr'
23
+
24
+ module Conjur
25
+ # Utility methods for CIDR network addresses
26
+ module CIDR
27
+ # Parse addr into an IPAddr if it's not one already, then extend it with CIDR
28
+ # module. This will force validation and will raise ArgumentError if invalid.
29
+ # @return [IPAddr] the address (extended with CIDR module)
30
+ def self.validate addr
31
+ addr = IPAddr.new addr unless addr.kind_of? IPAddr
32
+ addr.extend self
33
+ end
34
+
35
+ def self.extended addr
36
+ addr.prefixlen # validates
37
+ end
38
+
39
+ # Error raised when an address is not a valid CIDR network address
40
+ class InvalidCIDR < ArgumentError
41
+ end
42
+
43
+ attr_reader :mask_addr
44
+
45
+ # @return [String] the address as an "address/mask length" string
46
+ # @example
47
+ # IPAddr.new("192.0.2.0/255.255.255.0").extend(CIDR).to_s == "192.0.2.0/24"
48
+ def to_s
49
+ [super, prefixlen].join '/'
50
+ end
51
+
52
+ # @return [Fixnum] the length of the network mask prefix
53
+ def prefixlen
54
+ unless @prefixlen
55
+ return @prefixlen = 0 if (mask = mask_addr) == 0
56
+
57
+ @prefixlen = ipv4? ? 32 : 128
58
+
59
+ while (mask & 1) == 0
60
+ mask >>= 1
61
+ @prefixlen -= 1
62
+ end
63
+
64
+ if mask != ((1 << @prefixlen) - 1)
65
+ fail InvalidCIDR, "#{inspect} is not a valid CIDR network address"
66
+ end
67
+ end
68
+ return @prefixlen
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,4 @@
1
+ module Conjur
2
+ class FeatureNotAvailable < StandardError
3
+ end
4
+ end
@@ -0,0 +1,38 @@
1
+ #
2
+ # Copyright (C) 2014 Conjur Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'conjur/api'
22
+ require 'conjur/configuration'
23
+
24
+ class Conjur::Configuration
25
+ add_option :host_factory_url do
26
+ account_service_url 'host_factories', 500
27
+ end
28
+ end
29
+
30
+ class Conjur::API
31
+ class << self
32
+ def host_factory_asset_host
33
+ Conjur.configuration.host_factory_url
34
+ end
35
+ end
36
+ end
37
+
38
+ require 'conjur/api/host_factories'
data/lib/conjur/host.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
2
+ # Copyright (C) 2013-2015 Conjur Inc
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
5
  # this software and associated documentation files (the "Software"), to deal in
@@ -34,5 +34,24 @@ module Conjur
34
34
  end
35
35
  self['enrollment_url'].head{|response, request, result| response }.headers[:location]
36
36
  end
37
+
38
+ # Assign new attributes to the host. Currently, this method only lets you change the
39
+ # `:cidr` attribute.
40
+ #
41
+ # ### Permissions
42
+ # You must have update permission on the hosts's resource or be the host to
43
+ # update CIDR restrictions.
44
+ #
45
+ # @note This feature requires Conjur server version 4.6 or later.
46
+ #
47
+ # @param [Hash] options attributes to change
48
+ # @option options [Array<String, IPAddr>] :cidr the network restrictions for this host
49
+ # @return [void]
50
+ # @raise [ArgumentError] if cidr isn't valid
51
+ def update options
52
+ if cidr = options[:cidr]
53
+ set_cidr_restrictions cidr
54
+ end
55
+ end
37
56
  end
38
- end
57
+ end
@@ -0,0 +1,75 @@
1
+ #
2
+ # Copyright (C) 2014 Conjur Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'conjur/host_factory_token'
22
+
23
+ module Conjur
24
+ class HostFactory < RestClient::Resource
25
+ include ActsAsAsset
26
+
27
+ def roleid
28
+ attributes['roleid']
29
+ end
30
+
31
+ def role
32
+ Role.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_role_id(roleid).join('/')]
33
+ end
34
+
35
+ def deputy
36
+ Conjur::Deputy.new(Conjur::API.core_asset_host, options)["deputies/#{fully_escape id}"]
37
+ end
38
+
39
+ def deputy_api_key
40
+ attributes['deputy_api_key']
41
+ end
42
+
43
+ def create_token(expiration, options = {})
44
+ create_tokens(expiration, 1, options)[0]
45
+ end
46
+
47
+ def create_tokens(expiration, count, options = {})
48
+ parameters = options.merge({
49
+ expiration: expiration.iso8601,
50
+ count: count
51
+ })
52
+ response = RestClient::Resource.new(Conjur::API.host_factory_asset_host, self.options)[fully_escape id]["tokens"].post(parameters).body
53
+ JSON.parse(response).map do |attrs|
54
+ build_host_factory_token attrs
55
+ end
56
+ end
57
+
58
+ def tokens
59
+ # Tokens list is not returned by +show+ if the caller doesn't have permission
60
+ return nil unless self.attributes['tokens']
61
+
62
+ self.attributes['tokens'].collect do |attrs|
63
+ build_host_factory_token attrs
64
+ end
65
+ end
66
+
67
+ protected
68
+
69
+ def build_host_factory_token attrs
70
+ Conjur::HostFactoryToken.new(Conjur::API.host_factory_asset_host, self.options)["tokens"][attrs['token']].tap do |token|
71
+ token.attributes = attrs
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # Copyright (C) 2014 Conjur Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ module Conjur
22
+ class HostFactoryToken < RestClient::Resource
23
+ include HasAttributes
24
+
25
+ def to_json(options = {})
26
+ { token: token, expiration: expiration, cidr: cidr }
27
+ end
28
+
29
+ def token
30
+ self.url.split('/')[-1]
31
+ end
32
+
33
+ alias id token
34
+
35
+ def expiration
36
+ DateTime.iso8601(attributes['expiration'])
37
+ end
38
+
39
+ def host_factory
40
+ Conjur::HostFactory.new(Conjur::API.host_factory_asset_host, options)[fully_escape attributes['host_factory']['id']]
41
+ end
42
+
43
+ def cidr
44
+ attributes['cidr']
45
+ end
46
+
47
+ def revoke!
48
+ invalidate do
49
+ RestClient::Resource.new(self['revoke'].url, options).post
50
+ end
51
+ end
52
+
53
+ def save
54
+ raise "HostFactoryToken attributes are not updatable"
55
+ end
56
+
57
+ protected
58
+
59
+ def fetch
60
+ raise "HostFactoryToken attributes are not fetchable"
61
+ end
62
+ end
63
+ end
@@ -97,7 +97,7 @@ module Conjur
97
97
  # resource.permit 'execute', api.user('jon')
98
98
  # resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:user:jon']
99
99
  #
100
- # @param permission [String] the permission``
100
+ # @param permission [String] the permission
101
101
  # @param options [Hash, nil] extra options to pass to RestClient::Resource#get
102
102
  # @return [Array<String>] the ids of roles that have `permission` on this resource.
103
103
  def permitted_roles(permission, options = {})
data/lib/conjur/user.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
2
+ # Copyright (C) 2013-2015 Conjur Inc
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
5
  # this software and associated documentation files (the "Software"), to deal in
@@ -34,27 +34,35 @@ module Conjur
34
34
  # @return [String] the login for this user
35
35
  def login; id end
36
36
 
37
- # Assign new attributes to the user. Currently, this method only lets you change the
38
- # `:uidnumber` attribute.
37
+ # Assign new attributes to the user.
39
38
  #
40
39
  # If a user with the given `:uidnumber` already exists, this method will raise `RestClient::Forbidden`, with
41
40
  # the response body providing additional details if possible.
42
41
  #
43
42
  # ### Permissions
44
- # You must be a member of the user's role to call this method.
43
+ # You must be a member of the user's role to update the uidnumber.
44
+ # You must have update permission on the user's resource or be the user to
45
+ # update CIDR restrictions.
45
46
  #
46
- # @note This feature requires Conjur server version 4.3 or later.
47
+ # @note Updating `uidnumber` requires Conjur server version 4.3 or later.
48
+ # @note Updating `cidr` requires Conjur server version 4.6 or later.
47
49
  #
48
50
  # @param [Hash] options attributes to change
49
- # @option options [FixNum] :uidnumber the new uidnumber for this user. This option *must* be present.
51
+ # @option options [FixNum] :uidnumber the new uidnumber for this user.
52
+ # @option options [Array<String, IPAddr>] :cidr the network restrictions for this user. Requires Conjur server version 4.6 or later
50
53
  # @return [void]
51
54
  # @raise [RestClient::Conflict] if the uidnumber is already in use
52
- # @raise [ArgumentError] if uidnumber isn't a `Fixnum` or isn't present in `options`
55
+ # @raise [ArgumentError] if uidnumber or cidr aren't valid
53
56
  def update options
54
- # Currently the server raises a 400 Bad Request if uidnumber is missing, require it here
55
- raise ArgumentError "options[:uidnumber] is required" unless uidnumber = options[:uidnumber]
56
- raise ArgumentError, "options[:uidnumber] must be a Fixnum" unless uidnumber.kind_of?(Fixnum)
57
- self.put(options)
57
+ if uidnumber = options[:uidnumber]
58
+ # Currently the server raises a 400 Bad Request if uidnumber is missing, require it here
59
+ raise ArgumentError, "options[:uidnumber] must be a Fixnum" unless uidnumber.kind_of?(Fixnum)
60
+ self.put(options)
61
+ end
62
+
63
+ if cidr = options[:cidr]
64
+ set_cidr_restrictions cidr
65
+ end
58
66
  end
59
67
 
60
68
  # Get the user's uidnumber, which is used by LDAP and SSH login, among other things.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
2
+ # Copyright (C) 2013-2016 Conjur Inc
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
5
  # this software and associated documentation files (the "Software"), to deal in
@@ -205,5 +205,28 @@ module Conjur
205
205
  url << "?version=#{version}" if version
206
206
  self[url].get.body
207
207
  end
208
+
209
+ # Set the variable to expire after the given interval. The
210
+ # interval can either be an ISO8601 duration or it can the number
211
+ # of seconds for which the variable should be valid. Once a
212
+ # variable has expired, its value will no longer be retrievable.
213
+ #
214
+ # You must have the **`'update'`** permission on a variable to call this method.
215
+ #
216
+ # @example Use an ISO8601 duration to set the expiration for a variable to tomorrow
217
+ # var = api.variable 'my-secret'
218
+ # var.expires_in "P1D"
219
+ #
220
+ # @example Use ActiveSupport to set the expiration for a variable to tomorrow
221
+ # require 'active_support/all'
222
+ # var = api.variable 'my-secret'
223
+ # var.expires_in 1.day
224
+ # @param interval a String containing an ISO8601 duration, otherwise the number of seconds before the variable xpires
225
+ # @return [Hash] description of the variable's expiration, including the (Conjur server) time when it expires
226
+ def expires_in interval
227
+ duration = interval.respond_to?(:to_str) ? interval : "PT#{interval.to_i}S"
228
+ JSON::parse(self['expiration'].post(duration: duration).body)
229
+ end
230
+
208
231
  end
209
- end
232
+ end