simple_crowd 1.0.5 → 1.1.0
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.
- data/.document +5 -0
- data/Gemfile +7 -0
- data/Rakefile +1 -1
- data/lib/simple_crowd/cache/null_store.rb +86 -0
- data/lib/simple_crowd/client.rb +334 -298
- data/lib/simple_crowd/crowd_entity.rb +199 -199
- data/lib/simple_crowd/crowd_error.rb +24 -15
- data/lib/simple_crowd/group.rb +11 -11
- data/lib/simple_crowd/mappers/soap_attributes.rb +13 -13
- data/lib/simple_crowd/mock_client.rb +3 -2
- data/lib/simple_crowd/user.rb +17 -17
- data/lib/simple_crowd/version.rb +1 -1
- data/lib/simple_crowd.rb +53 -51
- data/simple_crowd.gemspec +19 -50
- data/test/crowd_config.yml.example +6 -6
- data/test/factories.rb +11 -9
- data/test/helper.rb +32 -28
- data/test/test_client.rb +329 -331
- data/test/test_simple_crowd.rb +22 -22
- data/test/test_user.rb +69 -69
- metadata +75 -158
@@ -1,13 +1,13 @@
|
|
1
|
-
module SimpleCrowd
|
2
|
-
module Mappers
|
3
|
-
class SoapAttributes
|
4
|
-
def self.produce hash
|
5
|
-
{"int:SOAPAttribute" => hash.inject([]) {|attrs, (key, val)| attrs << {"int:name" => key, "int:values" => {"wsdl:string" => val}}}}
|
6
|
-
end
|
7
|
-
def self.parse attributes
|
8
|
-
soap = attributes[:soap_attribute]
|
9
|
-
(soap && soap.inject({}) {|hash, attr| hash[attr[:name].to_sym] = attr[:values][:string]; hash }) || {}
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
1
|
+
module SimpleCrowd
|
2
|
+
module Mappers
|
3
|
+
class SoapAttributes
|
4
|
+
def self.produce hash
|
5
|
+
{"int:SOAPAttribute" => hash.inject([]) {|attrs, (key, val)| attrs << {"int:name" => key, "int:values" => {"wsdl:string" => val}}}}
|
6
|
+
end
|
7
|
+
def self.parse attributes
|
8
|
+
soap = attributes[:soap_attribute]
|
9
|
+
(soap && soap.inject({}) {|hash, attr| hash[attr[:name].to_sym] = attr[:values][:string]; hash }) || {}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -9,6 +9,8 @@ module SimpleCrowd
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
attr_accessor :app_token
|
13
|
+
|
12
14
|
@users = []
|
13
15
|
@tokens = []
|
14
16
|
@groups = []
|
@@ -19,7 +21,6 @@ module SimpleCrowd
|
|
19
21
|
def authenticate_application(name = nil, password = nil)
|
20
22
|
"MOCKAPPTOKEN"
|
21
23
|
end
|
22
|
-
alias_method :app_token, :authenticate_application
|
23
24
|
|
24
25
|
def authenticate_user name, password, factors = nil
|
25
26
|
(user = find_user_by_name(name)) && user.password && user.password == password ? new_user_token(name) : nil
|
@@ -112,4 +113,4 @@ module SimpleCrowd
|
|
112
113
|
def groups; self.class.groups; end
|
113
114
|
|
114
115
|
end
|
115
|
-
end
|
116
|
+
end
|
data/lib/simple_crowd/user.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
module SimpleCrowd
|
2
|
-
class User < CrowdEntity
|
3
|
-
|
4
|
-
# Immutable properties
|
5
|
-
property :id, :immutable => true
|
6
|
-
property :username, :immutable => true, :map_soap => :name
|
7
|
-
property :description, :immutable => true
|
8
|
-
property :active, :immutable => true, :default => true
|
9
|
-
property :directory_id, :immutable => true
|
10
|
-
|
11
|
-
# Assumed available attributes (with soap aliases)
|
12
|
-
property :first_name, :attribute => true, :map_soap => :givenName
|
13
|
-
property :last_name, :attribute => true, :map_soap => :sn
|
14
|
-
property :display_name, :attribute => true, :map_soap => :displayName
|
15
|
-
property :email, :attribute => true, :map_soap => :mail
|
16
|
-
end
|
17
|
-
end
|
1
|
+
module SimpleCrowd
|
2
|
+
class User < CrowdEntity
|
3
|
+
|
4
|
+
# Immutable properties
|
5
|
+
property :id, :immutable => true
|
6
|
+
property :username, :immutable => true, :map_soap => :name
|
7
|
+
property :description, :immutable => true
|
8
|
+
property :active, :immutable => true, :default => true
|
9
|
+
property :directory_id, :immutable => true
|
10
|
+
|
11
|
+
# Assumed available attributes (with soap aliases)
|
12
|
+
property :first_name, :attribute => true, :map_soap => :givenName
|
13
|
+
property :last_name, :attribute => true, :map_soap => :sn
|
14
|
+
property :display_name, :attribute => true, :map_soap => :displayName
|
15
|
+
property :email, :attribute => true, :map_soap => :mail
|
16
|
+
end
|
17
|
+
end
|
data/lib/simple_crowd/version.rb
CHANGED
data/lib/simple_crowd.rb
CHANGED
@@ -1,51 +1,53 @@
|
|
1
|
-
require 'savon'
|
2
|
-
require 'hashie'
|
3
|
-
require 'yaml'
|
4
|
-
require 'forwardable'
|
5
|
-
require 'simple_crowd/crowd_entity'
|
6
|
-
require 'simple_crowd/crowd_error'
|
7
|
-
require 'simple_crowd/user'
|
8
|
-
require 'simple_crowd/group'
|
9
|
-
require 'simple_crowd/client'
|
10
|
-
require 'simple_crowd/mappers/soap_attributes'
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
:
|
27
|
-
|
28
|
-
'xmlns:
|
29
|
-
'xmlns:
|
30
|
-
'xmlns:
|
31
|
-
'xmlns:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
:
|
39
|
-
:
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
1
|
+
require 'savon'
|
2
|
+
require 'hashie'
|
3
|
+
require 'yaml'
|
4
|
+
require 'forwardable'
|
5
|
+
require 'simple_crowd/crowd_entity'
|
6
|
+
require 'simple_crowd/crowd_error'
|
7
|
+
require 'simple_crowd/user'
|
8
|
+
require 'simple_crowd/group'
|
9
|
+
require 'simple_crowd/client'
|
10
|
+
require 'simple_crowd/mappers/soap_attributes'
|
11
|
+
require 'simple_crowd/cache/null_store'
|
12
|
+
Dir['simple_crowd/mappers/*.rb'].each {|file| require File.basename(file, File.extname(file)) }
|
13
|
+
|
14
|
+
module SimpleCrowd
|
15
|
+
class << self
|
16
|
+
def config &config_block
|
17
|
+
config_block.call(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def options app_options = {}
|
21
|
+
c = soap_options.merge(default_crowd_options).merge(app_options) and
|
22
|
+
c.merge(:service_url => c[:service_url] + 'services/SecurityServer')
|
23
|
+
end
|
24
|
+
def soap_options
|
25
|
+
@soap_options ||= {
|
26
|
+
:service_ns => "urn:SecurityServer",
|
27
|
+
:service_namespaces => {
|
28
|
+
'xmlns:auth' => 'http://authentication.integration.crowd.atlassian.com',
|
29
|
+
'xmlns:ex' => 'http://exception.integration.crowd.atlassian.com',
|
30
|
+
'xmlns:int' => 'http://soap.integration.crowd.atlassian.com',
|
31
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
32
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
def default_crowd_options
|
37
|
+
@default_crowd_options ||= {
|
38
|
+
:service_url => "http://localhost:8095/crowd/",
|
39
|
+
:app_name => "crowd",
|
40
|
+
:app_password => "",
|
41
|
+
:cache_prefix => "simple_crowd.",
|
42
|
+
}
|
43
|
+
defined?(IRB) ? @default_crowd_options.merge(config_file_options) : @default_crowd_options
|
44
|
+
end
|
45
|
+
def config_file_options
|
46
|
+
@config_file_options ||= begin
|
47
|
+
(File.exists?('config/crowd.yml') &&
|
48
|
+
yml = (YAML.load_file('config/crowd.yml')[ENV["RAILS_ENV"] || "development"] || {}) and
|
49
|
+
yml.symbolize_keys!) || {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/simple_crowd.gemspec
CHANGED
@@ -1,58 +1,27 @@
|
|
1
|
-
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
3
|
require 'simple_crowd/version'
|
3
4
|
|
4
5
|
Gem::Specification.new do |s|
|
5
|
-
s.name
|
6
|
-
s.version
|
7
|
-
s.
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.
|
11
|
-
|
12
|
-
|
13
|
-
s.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
lib/simple_crowd.rb
|
19
|
-
lib/simple_crowd/client.rb
|
20
|
-
lib/simple_crowd/crowd_entity.rb
|
21
|
-
lib/simple_crowd/crowd_error.rb
|
22
|
-
lib/simple_crowd/group.rb
|
23
|
-
lib/simple_crowd/mappers/soap_attributes.rb
|
24
|
-
lib/simple_crowd/mock_client.rb
|
25
|
-
lib/simple_crowd/user.rb
|
26
|
-
lib/simple_crowd/version.rb
|
27
|
-
simple_crowd.gemspec
|
28
|
-
test/crowd_config.yml.example
|
29
|
-
test/factories.rb
|
30
|
-
test/helper.rb
|
31
|
-
test/test_client.rb
|
32
|
-
test/test_simple_crowd.rb
|
33
|
-
test/test_user.rb
|
34
|
-
)
|
35
|
-
s.test_files = %w(
|
36
|
-
test/crowd_config.yml.example
|
37
|
-
test/factories.rb
|
38
|
-
test/helper.rb
|
39
|
-
test/test_client.rb
|
40
|
-
test/test_simple_crowd.rb
|
41
|
-
test/test_user.rb
|
42
|
-
)
|
43
|
-
s.homepage = %q{http://github.com/thinkwell/simple_crowd}
|
6
|
+
s.name = %q{simple_crowd}
|
7
|
+
s.version = SimpleCrowd::VERSION.dup
|
8
|
+
s.authors = ["Paul Strong"]
|
9
|
+
s.email = %q{paul@thestrongfamily.org}
|
10
|
+
s.homepage = %q{http://github.com/thinkwell/simple_crowd}
|
11
|
+
s.summary = %q{Simple Atlassian Crowd client using REST and SOAP APIs where needed.}
|
12
|
+
s.description = %q{Simple Atlassian Crowd client using REST and SOAP APIs where needed. Doesn't do any fancy object mapping, etc.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "simple_crowd"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
44
19
|
s.require_paths = ["lib"]
|
45
|
-
s.rubygems_version = %q{1.5.0}
|
46
|
-
s.summary = %q{Simple Atlassian Crowd client using REST and SOAP APIs where needed.}
|
47
20
|
|
48
|
-
s.
|
49
|
-
s.
|
50
|
-
|
51
|
-
s.add_development_dependency(%q<
|
52
|
-
s.add_development_dependency(%q<webmock>, [">= 0"])
|
53
|
-
s.add_development_dependency(%q<rr>, [">= 0"])
|
21
|
+
s.add_runtime_dependency(%q<savon>, ["~> 0.9.9"])
|
22
|
+
s.add_runtime_dependency(%q<hashie>, [">= 1.0.0"])
|
23
|
+
|
24
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.21"])
|
54
25
|
s.add_development_dependency(%q<rake>, [">= 0"])
|
55
|
-
s.add_runtime_dependency(%q<savon>, ["= 0.7.9"])
|
56
|
-
s.add_runtime_dependency(%q<hashie>, ["= 1.0.0"])
|
57
26
|
end
|
58
27
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
# Configure Crowd Test server for unit tests
|
2
|
-
# Replace default values with crowd server params
|
3
|
-
crowd:
|
4
|
-
service_url: http://www.crowdserver.com:8095/crowd/
|
5
|
-
app_name: crowdapp
|
6
|
-
app_password: testpass
|
1
|
+
# Configure Crowd Test server for unit tests
|
2
|
+
# Replace default values with crowd server params
|
3
|
+
crowd:
|
4
|
+
service_url: http://www.crowdserver.com:8095/crowd/
|
5
|
+
app_name: crowdapp
|
6
|
+
app_password: testpass
|
data/test/factories.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :user, :class => SimpleCrowd::User do
|
3
|
+
first_name 'Test'
|
4
|
+
last_name 'User'
|
5
|
+
display_name {|a| "#{a.first_name} #{a.last_name}"}
|
6
|
+
email {|a| "#{a.first_name}.#{a.last_name}@example.com".downcase }
|
7
|
+
sequence(:username) {|n| "test#{n}" }
|
8
|
+
# Clear dirty properties
|
9
|
+
after_build { |user| user.dirty_properties.clear }
|
10
|
+
end
|
11
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,28 +1,32 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
-
|
6
|
-
$CROWD_CONFIG_PATH = File.join(File.dirname(__FILE__), 'crowd_config.yml')
|
7
|
-
|
8
|
-
require 'simple_crowd'
|
9
|
-
require 'test/unit'
|
10
|
-
require 'shoulda'
|
11
|
-
require 'matchy'
|
12
|
-
require 'webmock/test_unit'
|
13
|
-
require 'rr'
|
14
|
-
require 'factory_girl'
|
15
|
-
require 'forgery'
|
16
|
-
|
17
|
-
# Load factories
|
18
|
-
require File.dirname(__FILE__) + "/factories"
|
19
|
-
|
20
|
-
WebMock.allow_net_connect!
|
21
|
-
|
22
|
-
class Test::Unit::TestCase
|
23
|
-
include
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
$CROWD_CONFIG_PATH = File.join(File.dirname(__FILE__), 'crowd_config.yml')
|
7
|
+
|
8
|
+
require 'simple_crowd'
|
9
|
+
require 'test/unit'
|
10
|
+
require 'shoulda'
|
11
|
+
require 'matchy'
|
12
|
+
require 'webmock/test_unit'
|
13
|
+
require 'rr'
|
14
|
+
require 'factory_girl'
|
15
|
+
require 'forgery'
|
16
|
+
|
17
|
+
# Load factories
|
18
|
+
require File.dirname(__FILE__) + "/factories"
|
19
|
+
|
20
|
+
WebMock.allow_net_connect!
|
21
|
+
|
22
|
+
class Test::Unit::TestCase
|
23
|
+
include RR::Adapters::TestUnit
|
24
|
+
def setup
|
25
|
+
WebMock.allow_net_connect!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Savon.configure do |config|
|
30
|
+
config.log = false
|
31
|
+
end
|
32
|
+
HTTPI.log = false
|
data/test/test_client.rb
CHANGED
@@ -1,331 +1,329 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestClient < Test::Unit::TestCase
|
4
|
-
CROWD_CONFIG = YAML.load_file($CROWD_CONFIG_PATH)['crowd']
|
5
|
-
context "A Client" do
|
6
|
-
setup do
|
7
|
-
@client = SimpleCrowd::Client.new({:service_url => CROWD_CONFIG['service_url'],
|
8
|
-
:app_name => CROWD_CONFIG['app_name'],
|
9
|
-
:app_password => CROWD_CONFIG['app_password']})
|
10
|
-
@service_url = @client.options[:service_url]
|
11
|
-
|
12
|
-
end
|
13
|
-
should "initialize" do
|
14
|
-
@client.should_not be nil
|
15
|
-
assert_instance_of SimpleCrowd::Client, @client
|
16
|
-
end
|
17
|
-
should "get app token" do
|
18
|
-
|
19
|
-
|
20
|
-
token
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
@client.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
info
|
40
|
-
info.
|
41
|
-
info[:
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
token
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
token
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
token
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
token_with_pass
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
token_with_pass.
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@client.
|
90
|
-
@client.is_valid_user_token?(
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
@
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
xmlns:
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
names
|
126
|
-
names.
|
127
|
-
names.
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
user.should_not be nil
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
user
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
user
|
149
|
-
user.
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
user
|
157
|
-
user.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
users
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
users
|
176
|
-
users.
|
177
|
-
|
178
|
-
users.
|
179
|
-
|
180
|
-
users
|
181
|
-
users.
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
@client.authenticate_user("test", "test").
|
194
|
-
@client.
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
user
|
202
|
-
user.
|
203
|
-
user.
|
204
|
-
|
205
|
-
|
206
|
-
@client.authenticate_user(localuser.username, "newuserpass").
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
updateduser
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
remoteuser = @client.
|
227
|
-
|
228
|
-
|
229
|
-
remoteuser.
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
remoteuser
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
remoteuser
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
remoteuser
|
254
|
-
remoteuser.
|
255
|
-
remoteuser.
|
256
|
-
|
257
|
-
remoteuser.
|
258
|
-
|
259
|
-
remoteuser.
|
260
|
-
|
261
|
-
remoteuser.
|
262
|
-
remoteuser.
|
263
|
-
|
264
|
-
remoteuser.
|
265
|
-
|
266
|
-
remoteuser
|
267
|
-
|
268
|
-
@client.
|
269
|
-
|
270
|
-
remoteuser
|
271
|
-
remoteuser.
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
is_true
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
names
|
295
|
-
names.
|
296
|
-
names.
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
@client.
|
302
|
-
@client.is_group_member?("Testing", "test").should be
|
303
|
-
@
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
#
|
308
|
-
#
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
@client.find_group_by_name("Testing")
|
313
|
-
|
314
|
-
updated_group
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
@client.
|
321
|
-
@
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
end
|
331
|
-
end
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestClient < Test::Unit::TestCase
|
4
|
+
CROWD_CONFIG = YAML.load_file($CROWD_CONFIG_PATH)['crowd']
|
5
|
+
context "A Client" do
|
6
|
+
setup do
|
7
|
+
@client = SimpleCrowd::Client.new({:service_url => CROWD_CONFIG['service_url'],
|
8
|
+
:app_name => CROWD_CONFIG['app_name'],
|
9
|
+
:app_password => CROWD_CONFIG['app_password']})
|
10
|
+
@service_url = @client.options[:service_url]
|
11
|
+
WebMock.reset!
|
12
|
+
end
|
13
|
+
should "initialize" do
|
14
|
+
@client.should_not be nil
|
15
|
+
assert_instance_of SimpleCrowd::Client, @client
|
16
|
+
end
|
17
|
+
should "get app token" do
|
18
|
+
@client.app_token.should be nil
|
19
|
+
@client.get_cookie_info
|
20
|
+
token = @client.app_token
|
21
|
+
token.should_not be nil
|
22
|
+
token.length.should == 24
|
23
|
+
|
24
|
+
assert_requested :post, @service_url, :times => 2
|
25
|
+
end
|
26
|
+
should "refresh app token if invalid" do
|
27
|
+
@client.app_token = "invalid"
|
28
|
+
@client.app_token.should == "invalid"
|
29
|
+
# making the token invalid should cause the client to refresh it
|
30
|
+
# and get the cookie info successfully
|
31
|
+
@client.get_cookie_info
|
32
|
+
# Validate refreshed token is same as original token
|
33
|
+
@client.app_token.should_not == "invalid"
|
34
|
+
assert_requested :post, @service_url, :times => 3
|
35
|
+
end
|
36
|
+
should "get cookie info" do
|
37
|
+
info = @client.get_cookie_info
|
38
|
+
info.should_not be nil
|
39
|
+
info[:domain].should_not be nil
|
40
|
+
info[:domain].length.should > 0
|
41
|
+
info[:secure].should_not be nil
|
42
|
+
assert_requested :post, @service_url, :times => 2
|
43
|
+
end
|
44
|
+
should "authenticate user" do
|
45
|
+
token = @client.authenticate_user "test", "test"
|
46
|
+
token.should_not be nil
|
47
|
+
token.length.should == 24
|
48
|
+
|
49
|
+
assert_requested :post, @service_url, :times => 2
|
50
|
+
end
|
51
|
+
should "authenticate user with validation factors" do
|
52
|
+
token = @client.authenticate_user "test", "test", {:test_factor => "test1234"}
|
53
|
+
token.should_not be nil
|
54
|
+
token.length.should == 24
|
55
|
+
|
56
|
+
assert_requested :post, @service_url, :times => 2
|
57
|
+
end
|
58
|
+
should "create user token without password" do
|
59
|
+
token = @client.create_user_token "test"
|
60
|
+
token.should_not be nil
|
61
|
+
token.length.should == 24
|
62
|
+
|
63
|
+
assert_requested :post, @service_url, :times => 2
|
64
|
+
end
|
65
|
+
should "return same user token with or without password" do
|
66
|
+
token_with_pass = @client.authenticate_user "test", "test"
|
67
|
+
token_with_pass.should_not be nil
|
68
|
+
token_with_pass.length.should == 24
|
69
|
+
token_without_pass = @client.create_user_token "test"
|
70
|
+
token_without_pass.should_not be nil
|
71
|
+
token_with_pass.length.should == 24
|
72
|
+
|
73
|
+
token_with_pass.should == token_without_pass
|
74
|
+
|
75
|
+
assert_requested :post, @service_url, :times => 3
|
76
|
+
end
|
77
|
+
should "validate user token" do
|
78
|
+
token = @client.authenticate_user "test", "test"
|
79
|
+
valid = @client.is_valid_user_token? token
|
80
|
+
valid.should be true
|
81
|
+
invalid = @client.is_valid_user_token?(token + "void")
|
82
|
+
invalid.should be false
|
83
|
+
assert_requested :post, @service_url, :times => 4
|
84
|
+
end
|
85
|
+
should "validate user token with factors" do
|
86
|
+
token = @client.authenticate_user "test", "test", {"Random-Number" => 6375}
|
87
|
+
@client.is_valid_user_token?(token).should be false
|
88
|
+
@client.is_valid_user_token?(token, {"Random-Number" => 6375}).should be true
|
89
|
+
token2 = @client.authenticate_user "test", "test"
|
90
|
+
@client.is_valid_user_token?(token2, {"Random-Number" => 48289}).should be false
|
91
|
+
assert_requested :post, @service_url, :times => 6
|
92
|
+
end
|
93
|
+
should "invalidate user token (logout)" do
|
94
|
+
token = @client.authenticate_user "test", "test"
|
95
|
+
@client.is_valid_user_token?(token).should be true
|
96
|
+
|
97
|
+
# Invalidate nonexistant token
|
98
|
+
@client.invalidate_user_token(token + "void").should be true
|
99
|
+
@client.is_valid_user_token?(token).should be true
|
100
|
+
|
101
|
+
# Invalidate token
|
102
|
+
@client.invalidate_user_token(token).should be true
|
103
|
+
@client.is_valid_user_token?(token).should be false
|
104
|
+
|
105
|
+
assert_requested :post, @service_url, :times => 7
|
106
|
+
end
|
107
|
+
should "reset user password" do
|
108
|
+
# Get real app token before mocking reset call
|
109
|
+
@client.app_token = @client.authenticate_application
|
110
|
+
WebMock.disable_net_connect!
|
111
|
+
|
112
|
+
response = %Q{<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
113
|
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
114
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
115
|
+
<soap:Body><ns1:resetPrincipalCredentialResponse xmlns:ns1="urn:SecurityServer" />
|
116
|
+
</soap:Body></soap:Envelope>
|
117
|
+
}
|
118
|
+
stub_request(:post, @service_url).to_return(:body => response, :status => 200)
|
119
|
+
|
120
|
+
@client.reset_user_password("test").should be true
|
121
|
+
end
|
122
|
+
should "find all user names" do
|
123
|
+
names = @client.find_all_user_names
|
124
|
+
names.should_not be nil
|
125
|
+
names.is_a?(Array).should be true
|
126
|
+
names.empty?.should be false
|
127
|
+
names.include?("test").should be true
|
128
|
+
end
|
129
|
+
should "find user by name" do
|
130
|
+
user = @client.find_user_by_name "test"
|
131
|
+
user.should_not be nil
|
132
|
+
[:id, :username, :description, :active, :directory_id, :first_name, :last_name, :email].each {|v| user.key?(v).should be true}
|
133
|
+
[:id, :username, :active, :directory_id].each {|v| user[v].should_not be nil}
|
134
|
+
assert_requested :post, @service_url, :times => 2
|
135
|
+
end
|
136
|
+
should "find user by token" do
|
137
|
+
token = @client.authenticate_user "test", "test"
|
138
|
+
user = @client.find_user_by_token token
|
139
|
+
user.should_not be nil
|
140
|
+
user.first_name.should == "Test"
|
141
|
+
|
142
|
+
assert_requested :post, @service_url, :times => 3
|
143
|
+
end
|
144
|
+
should "find username by token" do
|
145
|
+
token = @client.authenticate_user "test", "test"
|
146
|
+
user = @client.find_username_by_token token
|
147
|
+
user.should_not be nil
|
148
|
+
user.length.should > 0
|
149
|
+
user.should == "test"
|
150
|
+
|
151
|
+
assert_requested :post, @service_url, :times => 3
|
152
|
+
end
|
153
|
+
should "find user by email" do
|
154
|
+
user = @client.find_user_by_email "test@testing.com"
|
155
|
+
user.should_not be nil
|
156
|
+
user.first_name.should == "Test"
|
157
|
+
user.last_name.should == "User"
|
158
|
+
|
159
|
+
# partial searches should return nothing
|
160
|
+
user = @client.find_user_by_email "test"
|
161
|
+
user.should be nil
|
162
|
+
|
163
|
+
assert_requested :post, @service_url, :times => 3
|
164
|
+
end
|
165
|
+
should "search for users by email" do
|
166
|
+
users = @client.search_users_by_email "test"
|
167
|
+
users.empty?.should_not be true
|
168
|
+
users.all?{|u| u.email =~ /test/ }.should be true
|
169
|
+
|
170
|
+
assert_requested :post, @service_url, :times => 2
|
171
|
+
end
|
172
|
+
should "search users" do
|
173
|
+
users = @client.search_users({'principal.email' => "test@testing.com"})
|
174
|
+
users.should_not be nil
|
175
|
+
users.empty?.should_not be true
|
176
|
+
users.all?{|u| u.email == "test@testing.com" }.should be true
|
177
|
+
|
178
|
+
users = @client.search_users({'principal.fullname' => "Test"})
|
179
|
+
users.should_not be nil
|
180
|
+
users.empty?.should_not be true
|
181
|
+
users.each{|u| u.display_name.downcase.should =~ /test/ }
|
182
|
+
|
183
|
+
assert_requested :post, @service_url, :times => 3
|
184
|
+
end
|
185
|
+
should "return nil for nonexistant user" do
|
186
|
+
user = @client.find_user_by_name "nonexistant"
|
187
|
+
user.should be nil
|
188
|
+
assert_requested :post, @service_url, :times => 2
|
189
|
+
end
|
190
|
+
should "update user credential" do
|
191
|
+
@client.authenticate_user("test", "test").should_not be nil
|
192
|
+
@client.update_user_credential("test", "testupdate").should be true
|
193
|
+
lambda {@client.authenticate_user("test", "test")}.should raise_error
|
194
|
+
@client.authenticate_user("test", "testupdate").should_not be nil
|
195
|
+
@client.update_user_credential("test", "test").should be true
|
196
|
+
end
|
197
|
+
should "add/remove user" do
|
198
|
+
localuser = FactoryGirl.build(:user)
|
199
|
+
user = @client.add_user(localuser, "newuserpass")
|
200
|
+
user.should_not be nil
|
201
|
+
user.username.should == localuser.username
|
202
|
+
user.first_name.should == localuser.first_name
|
203
|
+
user.last_name.should == localuser.last_name
|
204
|
+
@client.authenticate_user(localuser.username, "newuserpass").should_not be nil
|
205
|
+
@client.remove_user(localuser.username).should be true
|
206
|
+
lambda {@client.authenticate_user(localuser.username, "newuserpass")}.should raise_error
|
207
|
+
|
208
|
+
assert_requested :post, @service_url, :times => 5
|
209
|
+
end
|
210
|
+
|
211
|
+
should "update user attribute" do
|
212
|
+
username = "test_update"
|
213
|
+
localuser = FactoryGirl.build(:user, :username => username)
|
214
|
+
remoteuser = @client.add_user(localuser, "updatepass")
|
215
|
+
@client.update_user_attribute(username, 'givenName', 'UpdatedFirst').should be true
|
216
|
+
updateduser = @client.find_user_by_name(username)
|
217
|
+
updateduser.last_name.should == localuser.last_name
|
218
|
+
updateduser.first_name.should == 'UpdatedFirst'
|
219
|
+
@client.remove_user username
|
220
|
+
end
|
221
|
+
should "update user custom attribute" do
|
222
|
+
username = "test_update"
|
223
|
+
localuser = FactoryGirl.build(:user, :username => username)
|
224
|
+
remoteuser = @client.add_user(localuser, "updatepass")
|
225
|
+
@client.update_user_attribute(username, 'customAttr', 'customVal').should be true
|
226
|
+
remoteuser = @client.find_user_with_attributes_by_name username
|
227
|
+
remoteuser.last_name.should == localuser.last_name
|
228
|
+
|
229
|
+
remoteuser[:customAttr].should == 'customVal'
|
230
|
+
@client.remove_user username
|
231
|
+
end
|
232
|
+
should "update user attribute array" do
|
233
|
+
username = "test_update"
|
234
|
+
localuser = FactoryGirl.build(:user, :username => username)
|
235
|
+
remoteuser = @client.add_user(localuser, "updatepass")
|
236
|
+
test_array = ["one", "two", "4"]
|
237
|
+
@client.update_user_attribute(username, 'arrayTest', test_array).should be true
|
238
|
+
remoteuser = @client.find_user_with_attributes_by_name username
|
239
|
+
remoteuser.last_name.should == localuser.last_name
|
240
|
+
remoteuser[:arrayTest].sort.should == test_array.sort
|
241
|
+
test_array.delete "two"
|
242
|
+
@client.update_user_attribute(username, 'arrayTest', test_array).should be true
|
243
|
+
remoteuser = @client.find_user_with_attributes_by_name username
|
244
|
+
remoteuser[:arrayTest].sort.should == test_array.sort
|
245
|
+
remoteuser[:arrayTest].include?("two").should be false
|
246
|
+
@client.remove_user username
|
247
|
+
end
|
248
|
+
should "update user" do
|
249
|
+
username = "test_update"
|
250
|
+
localuser = FactoryGirl.build(:user, :username => username)
|
251
|
+
remoteuser = @client.add_user(localuser, "updatepass")
|
252
|
+
remoteuser.should_not be nil
|
253
|
+
remoteuser.username.should == localuser.username
|
254
|
+
remoteuser.first_name.should == localuser.first_name
|
255
|
+
remoteuser.last_name.should == localuser.last_name
|
256
|
+
|
257
|
+
remoteuser.dirty?.should be false
|
258
|
+
# Should be ignored
|
259
|
+
remoteuser.active = false
|
260
|
+
remoteuser.first_name = "UpdatedFirst"
|
261
|
+
remoteuser.last_name = "UpdatedLast"
|
262
|
+
remoteuser.dirty?.should be true
|
263
|
+
|
264
|
+
remoteuser.dirty_attributes.should == [:first_name, :last_name]
|
265
|
+
|
266
|
+
@client.update_user(remoteuser)
|
267
|
+
|
268
|
+
remoteuser = @client.find_user_with_attributes_by_name username
|
269
|
+
remoteuser.first_name.should == "UpdatedFirst"
|
270
|
+
remoteuser.last_name.should == "UpdatedLast"
|
271
|
+
remoteuser.email.should == localuser.email
|
272
|
+
@client.remove_user username
|
273
|
+
end
|
274
|
+
should "check if cache enabled" do
|
275
|
+
enabled = @client.is_cache_enabled?
|
276
|
+
is_true = enabled.class == TrueClass
|
277
|
+
is_false = enabled.class == FalseClass
|
278
|
+
(is_true || is_false).should be true
|
279
|
+
end
|
280
|
+
should "get granted authorities" do
|
281
|
+
granted = @client.get_granted_authorities
|
282
|
+
(granted.nil? || (granted.is_a?(Array) && !granted.empty? && granted[0].is_a?(String))).should be true
|
283
|
+
|
284
|
+
assert_requested :post, @service_url, :times => 2
|
285
|
+
end
|
286
|
+
should "find group by name" do
|
287
|
+
group = @client.find_group_by_name("Testing")
|
288
|
+
group.should_not be nil
|
289
|
+
assert_requested :post, @service_url, :times => 2
|
290
|
+
end
|
291
|
+
should "find all group names" do
|
292
|
+
names = @client.find_all_group_names
|
293
|
+
names.should_not be nil
|
294
|
+
names.is_a?(Array).should be true
|
295
|
+
names.empty?.should be false
|
296
|
+
names.include?("Testing").should be true
|
297
|
+
end
|
298
|
+
should "add/remove user from group" do
|
299
|
+
@client.add_user_to_group("test", "Testing").should be true
|
300
|
+
@client.is_group_member?("Testing", "test").should be true
|
301
|
+
@client.remove_user_from_group("test", "Testing").should be true
|
302
|
+
@client.is_group_member?("Testing", "test").should be false
|
303
|
+
assert_requested :post, @service_url, :times => 5
|
304
|
+
end
|
305
|
+
# should "add/remove attribute from group" do
|
306
|
+
# @client.add_attribute_to_group("test", "tmpattribute", "Hello World").should be true
|
307
|
+
# @client.remove_attribute_from_group("test", "tmpattribute").should be true
|
308
|
+
# end
|
309
|
+
should "update group" do
|
310
|
+
@client.find_group_by_name("Testing").active.should be true
|
311
|
+
@client.update_group("Testing", "Test Description", false).should be true
|
312
|
+
updated_group = @client.find_group_by_name("Testing")
|
313
|
+
updated_group.active.should be false
|
314
|
+
updated_group.description.should == "Test Description"
|
315
|
+
@client.update_group("Testing", "", true).should be true
|
316
|
+
end
|
317
|
+
should "check if user is group member" do
|
318
|
+
@client.add_user_to_group("test", "Testing").should be true
|
319
|
+
@client.is_group_member?("Testing", "test").should be true
|
320
|
+
@client.is_group_member?("nonexistantgroup", "test").should be false
|
321
|
+
assert_requested :post, @service_url, :times => 4
|
322
|
+
end
|
323
|
+
should "accept cached app token" do
|
324
|
+
@client.app_token = "cachedtoken"
|
325
|
+
@client.app_token.should == "cachedtoken"
|
326
|
+
assert_not_requested :post, @service_url
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|