lib/artifactory/resources/permission_target.rb
module Artifactory class Resource::PermissionTarget < Resource::Base VERBOSE_PERMS = { 'd' => 'delete', 'm' => 'admin', 'n' => 'annotate', 'r' => 'read', 'w' => 'deploy', } class << self # # Get a list of all PermissionTargets in the system. # # @param [Hash] options # the list of options # # @option options [Artifactory::Client] :client # the client object to make the request with # # @return [Array<Resource::PermissionTarget>] # the list of PermissionTargets # def all(options = {}) client = extract_client!(options) client.get('/api/security/permissions').map do |hash| from_url(hash['uri'], client: client) end end # # Find (fetch) a permission target by its name. # # @example Find a permission target by its name # PermissionTarget.find('readers') #=> #<PermissionTarget name: 'readers' ...> # # @param [String] name # the name of the permission target to find # @param [Hash] options # the list of options # # @option options [Artifactory::Client] :client # the client object to make the request with # # @return [Resource::PermissionTarget, nil] # an instance of the permission target that matches the given name, or +nil+ # if one does not exist # def find(name, options = {}) client = extract_client!(options) response = client.get("/api/security/permissions/#{url_safe(name)}") from_hash(response, client: client) rescue Error::HTTPError => e raise unless e.code == 404 nil end # # @see Resource::Base.from_hash # Additionally use verbose names for permissions (e.g. 'read' for 'r') # def from_hash(hash, options = {}) super.tap do |instance| %w(users groups).each do |key| if instance.principals[key] && !instance.principals[key].nil? instance.principals[key] = Hash[instance.principals[key].map { |k, v| [k, verbose(v)] } ] end end end end private # # Replace an array of permissions with one using verbose permission names # def verbose(array) array.map { |elt| VERBOSE_PERMS[elt] }.sort end end class Principal attr_accessor :users, :groups def initialize(users = {}, groups = {}) @users = users @groups = groups end # # Converts the user-friendly form of the principals hash to one suitable # for posting to Artifactory. # @return [Hash] # def to_abbreviated { 'users' => abbreviate_principal(@users), 'groups' => abbreviate_principal(@groups) } end private # # Replace an array of verbose permission names with an equivalent array of abbreviated permission names. # def abbreviate_permissions(array) inverse = VERBOSE_PERMS.invert if (inverse.keys & array).sort != array.sort then raise "One of your principals contains an invalid permission. Valid permissions are #{inverse.keys.join(', ')}" end array.map { |elt| inverse[elt] }.sort end # # Replace a principal with verbose permissions with an equivalent one with abbreviated permissions. # def abbreviate_principal(principal_hash) Hash[principal_hash.map { |k, v| [k, abbreviate_permissions(v)] } ] end end attribute :name, ->{ raise 'Name missing!' } attribute :includes_pattern, '**' attribute :excludes_pattern, '' attribute :repositories attribute :principals, { 'users' => {}, 'groups' => {} } def client_principal @client_principal ||= Principal.new(principals['users'], principals['groups']) end # # Delete this PermissionTarget from artifactory, suppressing any +ResourceNotFound+ # exceptions might occur. # # @return [Boolean] # true if the object was deleted successfully, false otherwise # def delete client.delete(api_path) true rescue Error::HTTPError false end # # Save the PermissionTarget to the artifactory server. # See http://bit.ly/1qMOw0L # # @return [Boolean] # def save send("#{:principals}=", client_principal.to_abbreviated) client.put(api_path, to_json, headers) true end # # Getter for groups # def groups client_principal.groups end # # Setter for groups (groups_hash expected to be friendly) # def groups=(groups_hash) client_principal.groups = Hash[groups_hash.map { |k, v| [k, v.sort] } ] end # # Getter for users # def users client_principal.users end # # Setter for users (expecting users_hash to be friendly) # def users=(users_hash) client_principal.users = Hash[users_hash.map { |k, v| [k, v.sort] } ] end private # # The path to this PermissionTarget on the server. # # @return [String] # def api_path @api_path ||= "/api/security/permissions/#{url_safe(name)}" end # # The default headers for this object. This includes the +Content-Type+. # # @return [Hash] # def headers @headers ||= { 'Content-Type' => 'application/vnd.org.jfrog.artifactory.security.PermissionTarget+json' } end end end