lib/gooddata/models/membership.rb
# encoding: UTF-8
#
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
require 'multi_json'
require 'pmap'
require_relative 'project'
require_relative 'project_role'
require_relative 'user_group'
require_relative '../rest/object'
module GoodData
class Membership < Rest::Resource
attr_reader :json
ASSIGNABLE_MEMBERS = [
:email,
:first_name,
:last_name,
:login,
:phone,
:status,
:title
]
class << self
# Apply changes to object.
#
# @param obj [GoodData::User] Object to be modified
# @param changes [Hash] Hash with modifications
# @return [GoodData::User] Modified object
# def apply(obj, changes)
# changes.each do |param, val|
# next unless ASSIGNABLE_MEMBERS.include? param
# obj.send("#{param}=", val)
# end
# obj
# end
def create(data, options = { client: GoodData.connection })
c = client(options)
json = {
'user' => {
'content' => {
'email' => data[:email] || data[:login],
'login' => data[:login],
'firstname' => data[:first_name],
'lastname' => data[:last_name],
'userRoles' => ['editor'],
'password' => data[:password],
'domain' => data[:domain],
# And following lines are even much more ugly hack
# 'authentication_modes' => ['sso', 'password']
},
'links' => {},
'meta' => {}
}
}
json['user']['links']['self'] = data[:uri] if data[:uri]
c.create(self, json)
end
def diff_list(list1, list2)
GoodData::Helpers.diff(list1, list2, key: :login)
end
end
def initialize(json)
@json = json
end
# Checks objects for equality
#
# @param right [GoodData::User] Project to compare with
# @return [Boolean] True if same else false
def ==(other)
return false unless other.respond_to?(:to_hash)
to_hash == other.to_hash
# res = true
# ASSIGNABLE_MEMBERS.each do |k|
# l_val = send("#{k}")
# r_val = other.send("#{k}")
# res = false if l_val != r_val
# end
# res
end
# Checks objects for non-equality
#
# @param right [GoodData::User] Project to compare with
# @return [Boolean] True if different else false
def !=(other)
!(self == other)
end
# Apply changes to object.
#
# @param changes [Hash] Hash with modifications
# @return [GoodData::User] Modified object
# def apply(changes)
# GoodData::User.apply(self, changes)
# end
# Gets the contributor
#
# @return [String] Contributor
def contributor
url = @json['user']['meta']['contributor']
data = client.get url
client.create(GoodData::Membership, data)
end
# Gets date when created
#
# @return [DateTime] Created date
def created
Time.parse(@json['user']['meta']['created'])
end
# Is the member deleted?
#
# @return [Boolean] true if he is deleted
def deleted?
!(login =~ /^deleted-/).nil?
end
# Gets hash representing diff of users
#
# @param user [GoodData::User] Another profile to compare with
# @return [Hash] Hash representing diff
def diff(user)
GoodData::User.diff(self, user)
end
# Gets the email
#
# @return [String] Email address
def email
@json['user']['content']['email'] || ''
end
# Sets the email
#
# @param new_email [String] New email to be assigned
def email=(new_email)
@json['user']['content']['email'] = new_email
end
# Gets the first name
#
# @return [String] First name
def first_name
@json['user']['content']['firstname'] || ''
end
# Sets the first name
#
# @param new_first_name [String] New first name to be assigned
def first_name=(new_first_name)
@json['user']['content']['firstname'] = new_first_name
end
# Get full name
#
# @return String Full Name
# NOTE: This can be tricky to implement correctly for i18n
def full_name
"#{first_name} #{last_name}"
end
# Gets the invitations
#
# @return [Array<GoodData::Invitation>] List of invitations
def invitations
res = []
tmp = client.get @json['user']['links']['invitations']
tmp['invitations'].each do |_invitation|
# TODO: Something is missing here
end
res
end
# Gets the last name
#
# @return [String] Last name
def last_name
@json['user']['content']['lastname'] || ''
end
# Sets the last name
#
# @param new_last_name [String] New last name to be assigned
def last_name=(new_last_name)
@json['user']['content']['lastname'] = new_last_name
end
# Gets the login
#
# @return [String] Login
def login
@json['user']['content']['login'] || ''
end
# Sets the last name
#
# @param new_login [String] New login to be assigned
def login=(new_login)
@json['user']['content']['login'] = new_login
end
# Gets user raw object ID
#
# @return [String] Raw Object ID
def obj_id
uri.split('/').last
end
# Gets the permissions
#
# @return [Hash] Hash with permissions
def permissions
res = {}
tmp = client.get @json['user']['links']['permissions']
tmp['associatedPermissions']['permissions'].each do |permission_name, permission_value|
res[permission_name] = permission_value
end
res
end
# Gets the phone number
#
# @return [String] Phone number
def phone
@json['user']['content']['phonenumber'] || ''
end
# Sets the phone number
#
# @param new_phone_number [String] New phone number to be assigned
def phone=(new_phone_number)
@json['user']['content']['phonenumber'] = new_phone_number
end
# Gets profile of this membership
def profile
raw = client.get @json['user']['links']['self']
client.create(GoodData::Profile, raw)
end
# Gets URL of profile membership
def profile_url
@json['user']['links']['self']
end
# # Gets project which this membership relates to
# def project
# raw = client.get project_url
# client.create(GoodData::Project, raw)
# end
# Gets project id
def project_id
@json['user']['links']['roles'].split('/')[3]
end
# Gets project url
def project_url
@json['user']['links']['roles'].split('/')[0..3].join('/')
end
# Gets the projects of user
#
# @return [Array<GoodData::Project>] Array of projets
def projects
tmp = client.get @json['user']['links']['projects']
tmp['projects'].map do |project_meta|
project_uri = project_meta['project']['links']['self']
project = client.get project_uri
client.create(GoodData::Project, project)
end
end
# Gets first role
#
# @return [GoodData::ProjectRole] Array of project roles
def role
roles && roles.first
end
# Gets the project roles of user
#
# @return [Array<GoodData::ProjectRole>] Array of project roles
def roles
# TODO: Implement getting roles in project and cache them there
# See: https://jira.intgdc.com/browse/TMA-112
roles_link = GoodData::Helpers.get_path(@json, %w(user links roles))
return unless roles_link
tmp = client.get roles_link
tmp['associatedRoles']['roles'].pmap do |role_uri|
role = client.get role_uri
client.create(GoodData::ProjectRole, role)
end
end
# Gets the status
#
# @return [String] Status
def status
@json['user']['content']['status'] || ''
end
# Gets the title
#
# @return [String] User title
def title
@json['user']['meta']['title'] || ''
end
# Sets the title
#
# @param new_title [String] New title to be assigned
def title=(new_title)
@json['user']['content']['title'] = new_title
end
# Gets the date when updated
#
# @return [DateTime] Date of last update
def updated
DateTime.parse(@json['user']['meta']['updated'])
end
# Gets the object URI
#
# @return [String] Object URI
def uri
links['self']
end
# Enables membership
#
# @return [GoodData::Membership] returns self
def enable
self.status = 'ENABLED'
self
end
# Is the member enabled?
#
# @return [Boolean] true if it is enabled
def enabled?
status == 'ENABLED'
end
# Disables membership
#
# @return [GoodData::Membership] returns self
def disable
self.status = 'DISABLED'
self
end
# Is the member enabled?
#
# @return [Boolean] true if it is disabled
def disabled?
!enabled?
end
def data
data = @json || {}
data['user'] || {}
end
def name
(first_name || '') + (last_name || '')
end
def meta
data['meta'] || {}
end
def links
data['links'] || {}
end
def content
data['content'] || {}
end
def to_hash
tmp = GoodData::Helpers.symbolize_keys(content.merge(meta).merge('uri' => uri))
[
[:userRoles, :role],
[:companyName, :company_name],
[:phoneNumber, :phone_number],
[:firstname, :first_name],
[:lastname, :last_name],
[:authenticationModes, :authentication_modes]
].each do |vals|
wire, rb = vals
tmp[rb] = tmp[wire]
tmp.delete(wire)
end
tmp
end
def user_groups
project.user_groups(:all, user: obj_id)
end
private
# Sets status to 'ENABLED' or 'DISABLED'
def status=(new_status)
payload = {
'user' => {
'content' => {
'status' => new_status.to_s.upcase,
'userRoles' => @json['user']['content']['userRoles']
},
'links' => {
'self' => uri
}
}
}
res = client.post("/gdc/projects/#{project_id}/users", payload)
fail 'Update failed' unless res['projectUsersUpdateResult']['failed'].empty?
@json['user']['content']['status'] = new_status.to_s.upcase
self
end
end
end