mooset 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/config/sample +10 -3
- data/lib/mooset/application.rb +44 -17
- data/lib/mooset/endpoints/endpoint.rb +22 -9
- data/lib/mooset/endpoints/findable.rb +62 -0
- data/lib/mooset/endpoints/gitlab/group.rb +9 -3
- data/lib/mooset/endpoints/gitlab/group_search.rb +25 -22
- data/lib/mooset/endpoints/gitlab/paginate.rb +18 -0
- data/lib/mooset/endpoints/gitlab/user.rb +17 -3
- data/lib/mooset/endpoints/gitlab/user_search.rb +41 -21
- data/lib/mooset/endpoints/gitlab.rb +4 -8
- data/lib/mooset/endpoints/ldap/group.rb +9 -11
- data/lib/mooset/endpoints/ldap/ldap_search.rb +56 -0
- data/lib/mooset/endpoints/ldap/ou.rb +12 -0
- data/lib/mooset/endpoints/ldap/user.rb +8 -13
- data/lib/mooset/endpoints/ldap.rb +6 -18
- data/lib/mooset/endpoints/null.rb +46 -4
- data/lib/mooset/endpoints.rb +4 -3
- data/lib/mooset/resource.rb +18 -4
- data/lib/mooset/synchronize_group.rb +35 -0
- data/lib/mooset/version.rb +1 -1
- data/lib/mooset.rb +1 -2
- metadata +7 -9
- data/lib/mooset/endpoints/console_logger.rb +0 -10
- data/lib/mooset/endpoints/ldap/group_search.rb +0 -31
- data/lib/mooset/endpoints/ldap/user_search.rb +0 -31
- data/lib/mooset/storage.rb +0 -6
- data/lib/mooset/synchronize_users.rb +0 -9
- data/spec/mooset/endpoints/gitlab_spec.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 006161edeef876748ef7483011278a0a26f4098d
|
4
|
+
data.tar.gz: d93d1a0d851946612246a14b03e694a8743ed29c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7077ad440a847771fe16c8b3086b7c0e8d2a5dfff7d464ec96cb7b44279fc94ffc8fec43cf28e559bb127b659ec5cc1561db8a14470086f6824023ba59ea4fc9
|
7
|
+
data.tar.gz: e69db56d141bf63fbcdfe8c77df1b1cae798e67e9088104d4b6d3786c373456251558238a9ecd8e4d2de571dc7e8b0c2b3aa1dcb8e0f77b8484d6b7bfe59afa5
|
data/config/sample
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# vi:syntax=ruby
|
2
2
|
|
3
|
-
define :origin, :
|
3
|
+
define :origin, :ldap, {
|
4
4
|
host: 'localhost',
|
5
5
|
port: 389,
|
6
6
|
bind_dn: 'CN=user,OU=users,DC=domain,DC=com',
|
@@ -8,11 +8,18 @@ define :origin, :null, {
|
|
8
8
|
treebase: 'DC=domain,DC=com'
|
9
9
|
}
|
10
10
|
|
11
|
+
define :ldap_encrypted, :ldap, {
|
12
|
+
host: 'localhost',
|
13
|
+
port: 636,
|
14
|
+
bind_dn: 'CN=user,OU=users,DC=domain,DC=com',
|
15
|
+
bind_password: '',
|
16
|
+
treebase: 'DC=domain,DC=com',
|
17
|
+
encryption: :simple_tls
|
18
|
+
}
|
19
|
+
|
11
20
|
define :gitlab_dev, :gitlab, {
|
12
21
|
endpoint: 'http://gitlab',
|
13
22
|
private_token: ''
|
14
23
|
}
|
15
24
|
|
16
|
-
define :out, :console_logger
|
17
|
-
|
18
25
|
synchronize_users from: :origin, to: :output, query: '(&(memberof=CN=Users,DC=domain,DC=com)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))'
|
data/lib/mooset/application.rb
CHANGED
@@ -1,37 +1,54 @@
|
|
1
1
|
require 'optparse'
|
2
|
+
require 'irb'
|
3
|
+
require 'logger'
|
2
4
|
|
3
5
|
module Mooset
|
4
6
|
class Application
|
5
|
-
attr_accessor :config_filename
|
7
|
+
attr_accessor :config_filename, :interactive, :logfile
|
6
8
|
|
7
|
-
def define(endpoint_name, factory,
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def define(endpoint_name, factory, opts = {})
|
10
|
+
opts[:endpoint_name] = endpoint_name
|
11
|
+
opts[:logger] = logger
|
12
|
+
|
13
|
+
endpoints[endpoint_name] = Mooset::Endpoints::Endpoint.create(factory, opts)
|
14
|
+
end
|
15
|
+
|
16
|
+
def endpoints
|
17
|
+
@endpoints ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def logger
|
21
|
+
@logger ||= begin
|
22
|
+
l = ::Logger.new(logfile || STDOUT)
|
23
|
+
l.level = ::Logger::WARN
|
24
|
+
l
|
25
|
+
end
|
11
26
|
end
|
12
27
|
|
13
28
|
def instances
|
14
29
|
@instances ||= {}
|
15
30
|
end
|
16
31
|
|
17
|
-
def
|
18
|
-
|
32
|
+
def synchronize_group(from:, to:, **opts)
|
33
|
+
operations << Mooset::SynchronizeGroups.new(endpoints[from], endpoints[to], opts)
|
19
34
|
end
|
20
35
|
|
21
|
-
def
|
22
|
-
@
|
36
|
+
def operations
|
37
|
+
@operations ||= []
|
23
38
|
end
|
24
39
|
|
25
40
|
def run!
|
26
|
-
|
27
|
-
|
28
|
-
to = instances[event[:to]]
|
29
|
-
opts = event[:opts]
|
30
|
-
|
31
|
-
Mooset::SynchronizeUsers.call(from, to, opts)
|
41
|
+
operations.each do |operation|
|
42
|
+
operation.call
|
32
43
|
end
|
33
44
|
end
|
34
45
|
|
46
|
+
def start_irb
|
47
|
+
$app = self
|
48
|
+
|
49
|
+
IRB.start
|
50
|
+
end
|
51
|
+
|
35
52
|
def read_config
|
36
53
|
instance_eval File.read(config_filename), config_filename
|
37
54
|
end
|
@@ -45,12 +62,22 @@ module Mooset
|
|
45
62
|
|
46
63
|
OptionParser.new do |opts|
|
47
64
|
opts.banner = "Usage: #{$0} [options]"
|
65
|
+
opts.on("-f", "--logfile FILE", "Logfile", s.method(:logfile=))
|
66
|
+
opts.on("-v", "--verbose", "Verbose") do |x|
|
67
|
+
s.logger.level = ::Logger::INFO
|
68
|
+
end
|
69
|
+
|
48
70
|
opts.on("-c", "--config FILE", "Config file", s.method(:config_filename=))
|
71
|
+
opts.on("-i", "--interactive", "Run in interactive mode", s.method(:interactive=))
|
49
72
|
opts.parse!(argv)
|
50
73
|
end
|
51
74
|
|
52
|
-
s.
|
53
|
-
|
75
|
+
if s.config_filename
|
76
|
+
s.read_config
|
77
|
+
s.run! unless s.interactive
|
78
|
+
end
|
79
|
+
|
80
|
+
s.start_irb if s.interactive
|
54
81
|
end
|
55
82
|
|
56
83
|
end
|
@@ -5,13 +5,8 @@ module Mooset
|
|
5
5
|
class Endpoint
|
6
6
|
include Virtus.model
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(endpoint_name, *args)
|
11
|
-
@endpoint_name = endpoint_name
|
12
|
-
|
13
|
-
super(*args)
|
14
|
-
end
|
8
|
+
attribute :logger
|
9
|
+
attribute :endpoint_name
|
15
10
|
|
16
11
|
def self.inherited(klass)
|
17
12
|
super
|
@@ -32,8 +27,26 @@ module Mooset
|
|
32
27
|
downcase
|
33
28
|
end
|
34
29
|
|
35
|
-
def self.create(name,
|
36
|
-
descendants[name].new(
|
30
|
+
def self.create(name, opts = {})
|
31
|
+
descendants[name].new(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.resources
|
35
|
+
@resources ||= []
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.resource(name, &block)
|
39
|
+
resources << name
|
40
|
+
|
41
|
+
define_method(name) do
|
42
|
+
r = instance_variable_get("@#{name}")
|
43
|
+
if r.nil?
|
44
|
+
r = instance_eval(&block)
|
45
|
+
instance_variable_set("@#{name}", r)
|
46
|
+
end
|
47
|
+
r
|
48
|
+
end
|
49
|
+
|
37
50
|
end
|
38
51
|
end
|
39
52
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Mooset
|
2
|
+
module Endpoints
|
3
|
+
module Findable
|
4
|
+
module ClassMethods
|
5
|
+
def import(name, &block)
|
6
|
+
define_method(import_method_name(name), &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def finder(name, &block)
|
10
|
+
define_method(finder_method_name(name), &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def finder_method_name(name)
|
14
|
+
"find_by_#{name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def import_method_name(name)
|
18
|
+
"import_from_#{name}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module InstanceMethods
|
23
|
+
def import(object)
|
24
|
+
method = self.class.import_method_name(object.provider)
|
25
|
+
|
26
|
+
public_send(method, object)
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_from_object(object, *args)
|
30
|
+
finder = object.finders.find { |x| respond_to? self.class.finder_method_name(x) }
|
31
|
+
|
32
|
+
if finder && object[finder]
|
33
|
+
public_send(self.class.finder_method_name(finder), object[finder], *args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_from_hash(hash)
|
38
|
+
key, value = hash.find { |(k, _)| respond_to? self.class.finder_method_name(k) }
|
39
|
+
|
40
|
+
args = hash.tap do |h|
|
41
|
+
h.delete(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
if key && value
|
45
|
+
public_send(self.class.finder_method_name(key), value, args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def find(opts, *args)
|
50
|
+
return find_from_hash(opts, *args) if opts.is_a? Hash
|
51
|
+
|
52
|
+
find_from_object(opts, args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.included(receiver)
|
57
|
+
receiver.extend ClassMethods
|
58
|
+
receiver.send :include, InstanceMethods
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -8,14 +8,18 @@ module Mooset
|
|
8
8
|
MASTER = 40
|
9
9
|
OWNER = 50
|
10
10
|
|
11
|
+
attribute :gitlab_id
|
11
12
|
attribute :path
|
12
13
|
attribute :owner_id
|
13
14
|
attribute :provider, String, default: "gitlab"
|
14
15
|
|
15
|
-
|
16
|
+
finders [:gitlab_id, :name]
|
17
|
+
|
18
|
+
def self.build(endpoint, group)
|
16
19
|
new(
|
17
|
-
|
20
|
+
endpoint: endpoint,
|
18
21
|
id: group.id,
|
22
|
+
gitlab_id: group.id,
|
19
23
|
name: group.name,
|
20
24
|
path: group.path,
|
21
25
|
owner_id: group.owner_id
|
@@ -23,10 +27,12 @@ module Mooset
|
|
23
27
|
end
|
24
28
|
|
25
29
|
def members
|
26
|
-
endpoint.users.
|
30
|
+
@members ||= endpoint.users.group_members(id).to_a
|
27
31
|
end
|
28
32
|
|
29
33
|
def <<(user)
|
34
|
+
@logger.info "add_group_member #{id} #{user.id} DEVELOPER"
|
35
|
+
|
30
36
|
endpoint.groups.add_group_member(id, user.id, DEVELOPER)
|
31
37
|
end
|
32
38
|
end
|
@@ -2,6 +2,9 @@ module Mooset
|
|
2
2
|
module Endpoints
|
3
3
|
class Gitlab
|
4
4
|
class GroupSearch
|
5
|
+
include Paginate
|
6
|
+
include Findable
|
7
|
+
|
5
8
|
attr_reader :endpoint
|
6
9
|
|
7
10
|
def initialize(endpoint)
|
@@ -9,39 +12,39 @@ module Mooset
|
|
9
12
|
end
|
10
13
|
|
11
14
|
def all
|
12
|
-
|
13
|
-
objects = []
|
15
|
+
return to_enum(:all) unless block_given?
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
page += 1
|
18
|
-
end
|
17
|
+
paginate ->(page){ connection.groups(page: page) }, ->(object){ yield Group.build(endpoint, object) }
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
20
|
+
finder :all do |_, opts = {}|
|
21
|
+
all
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
Group.build(endpoint
|
24
|
+
finder :id do |id, opts = {}|
|
25
|
+
Group.build(endpoint, connection.group(id))
|
27
26
|
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
finder :gitlab_id do |gitlab_id, opts = {}|
|
29
|
+
find(id: gitlab_id)
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
finder :name do |name, opts = {}|
|
33
|
+
all.find { |x| x.name == name }
|
34
|
+
end
|
35
|
+
|
36
|
+
import :ldap do |group, opts = {}|
|
37
|
+
create(group.name, group.name.gsub(/( )/, '_').downcase)
|
38
|
+
end
|
39
|
+
|
40
|
+
def members(id)
|
41
|
+
return to_enum(:members, id) unless block_given?
|
37
42
|
|
38
|
-
|
39
|
-
User.build(endpoint.endpoint_name, object)
|
40
|
-
end
|
43
|
+
paginate ->(page){ connection.group_members(id, page: page) }, ->(object){ yield User.build(endpoint, object) }
|
41
44
|
end
|
42
45
|
|
43
46
|
def create(name, path)
|
44
|
-
Group.build(endpoint
|
47
|
+
Group.build(endpoint, connection.create_group(name, path))
|
45
48
|
end
|
46
49
|
|
47
50
|
def add_group_member(team_id, user_id, access_level = 50)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Mooset
|
2
|
+
module Endpoints
|
3
|
+
class Gitlab
|
4
|
+
module Paginate
|
5
|
+
def paginate(lookup, builder)
|
6
|
+
page = 1
|
7
|
+
|
8
|
+
while (o = lookup.call(page)).length > 0 do
|
9
|
+
o.each do |oo|
|
10
|
+
builder.call(oo)
|
11
|
+
end
|
12
|
+
page += 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,21 +2,35 @@ module Mooset
|
|
2
2
|
module Endpoints
|
3
3
|
class Gitlab
|
4
4
|
class User < Models::User
|
5
|
+
attribute :gitlab_id
|
5
6
|
attribute :state
|
6
7
|
attribute :access_level
|
7
8
|
attribute :provider, String, default: "gitlab"
|
9
|
+
attribute :ldap_id, String
|
8
10
|
|
9
|
-
|
11
|
+
finders [:gitlab_id, :ldap_id, :email, :username]
|
12
|
+
|
13
|
+
def self.build(endpoint, user)
|
10
14
|
self.new(
|
11
|
-
|
15
|
+
endpoint: endpoint,
|
12
16
|
id: user.id,
|
17
|
+
gitlab_id: user.id,
|
13
18
|
username: user.username,
|
14
19
|
full_name: user.name,
|
15
20
|
state: user.state,
|
16
21
|
email: user.email,
|
17
|
-
access_level: user.access_level
|
22
|
+
access_level: user.access_level,
|
23
|
+
ldap_id: Optional.new(user).identities.within do |identities|
|
24
|
+
identity_from(Many.new(identities)).values.first
|
25
|
+
end.value,
|
18
26
|
)
|
19
27
|
end
|
28
|
+
|
29
|
+
def self.identity_from(identities)
|
30
|
+
identities.within do |o|
|
31
|
+
o["extern_uid"] if o["provider"] == 'ldap'
|
32
|
+
end
|
33
|
+
end
|
20
34
|
end
|
21
35
|
end
|
22
36
|
end
|
@@ -2,6 +2,9 @@ module Mooset
|
|
2
2
|
module Endpoints
|
3
3
|
class Gitlab
|
4
4
|
class UserSearch
|
5
|
+
include Paginate
|
6
|
+
include Findable
|
7
|
+
|
5
8
|
attr_reader :endpoint
|
6
9
|
|
7
10
|
def initialize(endpoint)
|
@@ -9,35 +12,52 @@ module Mooset
|
|
9
12
|
end
|
10
13
|
|
11
14
|
def all
|
12
|
-
|
13
|
-
|
15
|
+
return to_enum(:all) unless block_given?
|
16
|
+
|
17
|
+
paginate ->(page){ connection.users(page: page) }, ->(object){ yield User.build(endpoint, object) }
|
18
|
+
end
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
20
|
+
def alll
|
21
|
+
@alll ||= all.to_a
|
22
|
+
end
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
24
|
+
finder :id do |id, opts = {}|
|
25
|
+
User.build(endpoint, connection.user(id))
|
23
26
|
end
|
24
27
|
|
25
|
-
|
26
|
-
|
28
|
+
finder :gitlab_id do |gitlab_id, opts = {}|
|
29
|
+
find(id: gitlab_id)
|
27
30
|
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
finder :username do |username, opts = {}|
|
33
|
+
alll.find { |x| x.username == username }
|
34
|
+
end
|
35
|
+
|
36
|
+
finder :email do |email, opts = {}|
|
37
|
+
alll.find { |x| x.email == email }
|
38
|
+
end
|
39
|
+
|
40
|
+
finder :dn do |dn, opts = {}|
|
41
|
+
alll.find { |x| x.ldap_id == dn }
|
42
|
+
end
|
43
|
+
|
44
|
+
import :ldap do |user|
|
45
|
+
create(user.email, SecureRandom.hex(8), {
|
46
|
+
name: user.full_name,
|
47
|
+
username: user.username,
|
48
|
+
extern_uid: user.dn,
|
49
|
+
provider: 'ldap',
|
50
|
+
})
|
51
|
+
end
|
52
|
+
|
53
|
+
def create(email, password, opts = {})
|
54
|
+
User.build(endpoint, connection.create_user(email, password, opts))
|
55
|
+
end
|
32
56
|
|
33
|
-
|
34
|
-
|
35
|
-
page += 1
|
36
|
-
end
|
57
|
+
def group_members(id, &block)
|
58
|
+
return to_enum(:group_members, id) unless block_given?
|
37
59
|
|
38
|
-
|
39
|
-
User.build(endpoint.endpoint_name, object)
|
40
|
-
end
|
60
|
+
paginate ->(page){ connection.group_members(id, page: page) }, ->(object){ block.call User.build(endpoint, object) }
|
41
61
|
end
|
42
62
|
|
43
63
|
private
|
@@ -13,16 +13,12 @@ module Mooset
|
|
13
13
|
})
|
14
14
|
}
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
}
|
19
|
-
|
20
|
-
def users
|
21
|
-
@users ||= UserSearch.new(self)
|
16
|
+
resource :users do
|
17
|
+
UserSearch.new(self)
|
22
18
|
end
|
23
19
|
|
24
|
-
|
25
|
-
|
20
|
+
resource :groups do
|
21
|
+
GroupSearch.new(self)
|
26
22
|
end
|
27
23
|
|
28
24
|
def write(user)
|
@@ -2,24 +2,22 @@ module Mooset
|
|
2
2
|
module Endpoints
|
3
3
|
class Ldap
|
4
4
|
class Group < Models::Group
|
5
|
+
attribute :dn, String
|
5
6
|
attribute :provider, String, default: "ldap"
|
7
|
+
finders [:dn, :name]
|
6
8
|
|
7
|
-
def self.build(
|
9
|
+
def self.build(endpoint, params)
|
8
10
|
group = Optional.new(params)
|
9
11
|
new(
|
10
|
-
|
11
|
-
id: group[:dn].value,
|
12
|
-
|
13
|
-
|
14
|
-
users_from(endpoint_name, Many.new(users)).values
|
15
|
-
end.value,
|
12
|
+
endpoint: endpoint,
|
13
|
+
id: group[:dn].first.value,
|
14
|
+
dn: group[:dn].first.value,
|
15
|
+
name: group[:cn].first.value
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
users.
|
21
|
-
Ldap::User.build(endpoint_name, id: user)
|
22
|
-
end
|
19
|
+
def members
|
20
|
+
endpoint.users.find(memberof: id)
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Mooset
|
2
|
+
module Endpoints
|
3
|
+
class Ldap
|
4
|
+
class LdapSearch
|
5
|
+
include Findable
|
6
|
+
GROUP_FILTER = "(objectClass=group)"
|
7
|
+
|
8
|
+
attr_reader :endpoint
|
9
|
+
|
10
|
+
def initialize(endpoint, default_search)
|
11
|
+
@endpoint = endpoint
|
12
|
+
@default_search = default_search
|
13
|
+
end
|
14
|
+
|
15
|
+
finder :dn do |dn, base: nil|
|
16
|
+
s = base.nil? ? @default_search : dn
|
17
|
+
b = base.nil? ? dn : base
|
18
|
+
|
19
|
+
query(s, base: b)
|
20
|
+
end
|
21
|
+
|
22
|
+
finder :name do |name, opts = {}|
|
23
|
+
query("(&(objectclass=group)(cn=#{name}))")
|
24
|
+
end
|
25
|
+
|
26
|
+
finder :memberof do |dn, base: endpoint.treebase|
|
27
|
+
query("(&(objectclass=person)(memberof=#{dn})(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))", base: base)
|
28
|
+
end
|
29
|
+
|
30
|
+
def query(filter = @default_search, base: endpoint.treebase)
|
31
|
+
return to_enum(:query, filter, base: base) unless block_given?
|
32
|
+
|
33
|
+
connection.search(base: base, filter: filter) do |object|
|
34
|
+
if object[:objectclass] && object[:objectclass].include?("group")
|
35
|
+
r = Group.build(endpoint, object)
|
36
|
+
elsif object[:objectclass] && object[:objectclass].include?("user")
|
37
|
+
r = User.build(endpoint, object)
|
38
|
+
elsif object[:objectclass] && object[:objectclass].include?("organizationalUnit")
|
39
|
+
r = Ou.build(endpoint, object)
|
40
|
+
else
|
41
|
+
raise "Unknown objectclass #{object[:objectclass]}"
|
42
|
+
end
|
43
|
+
|
44
|
+
yield r
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def connection
|
51
|
+
@endpoint.connection
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -41,26 +41,21 @@ module Mooset
|
|
41
41
|
end
|
42
42
|
|
43
43
|
class User < Models::User
|
44
|
-
|
44
|
+
finders [:dn, :username, :email]
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
Ldap::Group.build(endpoint_name, id: group)
|
49
|
-
end
|
50
|
-
end
|
46
|
+
attribute :provider, String, default: "ldap"
|
47
|
+
attribute :dn, String
|
51
48
|
|
52
|
-
def self.build(
|
49
|
+
def self.build(endpoint, params)
|
53
50
|
user = Optional.new(params)
|
54
51
|
|
55
52
|
self.new(
|
56
|
-
|
57
|
-
id: user[:dn].value,
|
58
|
-
dn: user[:dn].value,
|
53
|
+
endpoint: endpoint,
|
54
|
+
id: user[:dn].first.value,
|
55
|
+
dn: user[:dn].first.value,
|
59
56
|
email: user[:mail].first.value,
|
60
57
|
full_name: user[:cn].first.value,
|
61
|
-
username: user[:sAMAccountName].value,
|
62
|
-
memberof: user[:memberof].within { |groups| groups_from(endpoint_name, Many.new(groups)).values }.value,
|
63
|
-
useraccountcontrol: AccountControl.decode(user[:useraccountcontrol][0].to_i),
|
58
|
+
username: user[:sAMAccountName].first.value,
|
64
59
|
)
|
65
60
|
end
|
66
61
|
end
|
@@ -11,38 +11,26 @@ module Mooset
|
|
11
11
|
attribute :bind_dn, String
|
12
12
|
attribute :bind_password, String
|
13
13
|
attribute :treebase, String
|
14
|
+
attribute :encryption, Symbol
|
14
15
|
attribute :connection, Object, default: Proc.new { |ldap, attribute|
|
15
16
|
connection = Net::LDAP.new
|
16
17
|
connection.host = ldap.host
|
17
18
|
connection.port = ldap.port
|
19
|
+
connection.encryption(ldap.encryption)
|
18
20
|
connection.auth ldap.bind_dn, ldap.bind_password
|
19
21
|
connection
|
20
22
|
}
|
21
23
|
|
22
|
-
attribute :storage, Object, default: Proc.new { Storage::Memory.new(name) }
|
23
|
-
|
24
24
|
def write(*user)
|
25
25
|
raise "Read only endpoint"
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def find(dn)
|
33
|
-
Many.new(query("(objectClass=*)", base: dn)).within do |data|
|
34
|
-
if data[:objectclass] && data[:objectclass].include?("group")
|
35
|
-
Group.build(connection, data)
|
36
|
-
elsif data[:objectclass] && data[:objectclass].include?("user")
|
37
|
-
User.build(connection, data)
|
38
|
-
else
|
39
|
-
raise "Unknown objectclass"
|
40
|
-
end
|
41
|
-
end.values.first
|
28
|
+
resource :users do
|
29
|
+
LdapSearch.new(self, "(objectClass=person)")
|
42
30
|
end
|
43
31
|
|
44
|
-
|
45
|
-
|
32
|
+
resource :groups do
|
33
|
+
LdapSearch.new(self, "(|(objectClass=group)(objectClass=organizationalUnit))")
|
46
34
|
end
|
47
35
|
end
|
48
36
|
end
|
@@ -1,12 +1,54 @@
|
|
1
1
|
module Mooset
|
2
2
|
module Endpoints
|
3
3
|
class Null < Endpoint
|
4
|
-
|
5
|
-
|
4
|
+
class U
|
5
|
+
#include Findable
|
6
|
+
|
7
|
+
def create(u)
|
8
|
+
Models::User.new(id: u.id, username: u.username, email: u.email)
|
9
|
+
end
|
10
|
+
|
11
|
+
def import(from, *args)
|
12
|
+
@logger.info(from, *args)
|
13
|
+
end
|
14
|
+
|
15
|
+
#import :ldap do |u|
|
16
|
+
#create(u)
|
17
|
+
#end
|
18
|
+
end
|
19
|
+
|
20
|
+
class G
|
21
|
+
include Findable
|
22
|
+
|
23
|
+
def create(u)
|
24
|
+
model = Models::Group.new(id: u.id, name: u.name)
|
25
|
+
model.send :define_singleton_method, :'<<' do |other|
|
26
|
+
@logger.info "#{self.id} << #{other.id}"
|
27
|
+
end
|
28
|
+
|
29
|
+
model
|
30
|
+
end
|
31
|
+
|
32
|
+
import :gitlab do |o|
|
33
|
+
logger.info o
|
34
|
+
end
|
35
|
+
|
36
|
+
import :ldap do |gr|
|
37
|
+
g = create(gr)
|
38
|
+
g.send :define_singleton_method, :members do
|
39
|
+
[]
|
40
|
+
end
|
41
|
+
g
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
resource :users do
|
47
|
+
U.new
|
6
48
|
end
|
7
49
|
|
8
|
-
|
9
|
-
|
50
|
+
resource :groups do
|
51
|
+
G.new
|
10
52
|
end
|
11
53
|
end
|
12
54
|
end
|
data/lib/mooset/endpoints.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
require 'mooset/endpoints/endpoint'
|
2
|
+
require 'mooset/endpoints/findable'
|
2
3
|
require 'mooset/endpoints/gitlab'
|
3
4
|
require 'mooset/endpoints/gitlab/user'
|
4
5
|
require 'mooset/endpoints/gitlab/group'
|
6
|
+
require 'mooset/endpoints/gitlab/paginate'
|
5
7
|
require 'mooset/endpoints/gitlab/user_search'
|
6
8
|
require 'mooset/endpoints/gitlab/group_search'
|
7
9
|
require 'mooset/endpoints/ldap'
|
8
10
|
require 'mooset/endpoints/ldap/user'
|
9
11
|
require 'mooset/endpoints/ldap/group'
|
10
|
-
require 'mooset/endpoints/ldap/
|
11
|
-
require 'mooset/endpoints/ldap/
|
12
|
-
require 'mooset/endpoints/console_logger'
|
12
|
+
require 'mooset/endpoints/ldap/ou'
|
13
|
+
require 'mooset/endpoints/ldap/ldap_search'
|
13
14
|
require 'mooset/endpoints/null'
|
14
15
|
|
15
16
|
module Mooset
|
data/lib/mooset/resource.rb
CHANGED
@@ -2,15 +2,29 @@ module Mooset
|
|
2
2
|
class Resource
|
3
3
|
include Virtus.model
|
4
4
|
|
5
|
-
|
6
|
-
attribute :endpoint_name
|
5
|
+
attr_reader :endpoint
|
7
6
|
|
8
|
-
def
|
9
|
-
|
7
|
+
def self.finders(finder_list)
|
8
|
+
define_method :finders do
|
9
|
+
finder_list
|
10
|
+
end
|
10
11
|
end
|
11
12
|
|
12
13
|
def initialize(*args)
|
14
|
+
@endpoint = args[0][:endpoint]
|
15
|
+
|
13
16
|
super(*args)
|
17
|
+
|
18
|
+
@logger = ::Logger.new(STDOUT)
|
19
|
+
@logger.info "{endpoint_name} -- build #{self.class.name} #{args.join(" ")}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_json(*args)
|
23
|
+
attributes.to_json
|
24
|
+
end
|
25
|
+
|
26
|
+
def finders
|
27
|
+
[]
|
14
28
|
end
|
15
29
|
end
|
16
30
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Mooset
|
2
|
+
class SynchronizeGroups
|
3
|
+
attr_accessor :from, :to, :opts
|
4
|
+
|
5
|
+
def initialize(from, to, opts)
|
6
|
+
@from = from
|
7
|
+
@to = to
|
8
|
+
@opts = opts
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
@from.groups.find(@opts[:query]).each do |group|
|
13
|
+
to_group = @to.groups.find(group)
|
14
|
+
|
15
|
+
if !to_group
|
16
|
+
to_group = @to.groups.import(group)
|
17
|
+
end
|
18
|
+
|
19
|
+
to_member_ids = to_group.members.map(&:id)
|
20
|
+
|
21
|
+
group.members.each do |user|
|
22
|
+
#next unless user.id =~ /Alexandru/
|
23
|
+
|
24
|
+
to_user = @to.users.find(user)
|
25
|
+
|
26
|
+
if !to_user
|
27
|
+
to_user = @to.users.import(user)
|
28
|
+
end
|
29
|
+
|
30
|
+
to_group << to_user unless to_member_ids.include?(to_user.id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/mooset/version.rb
CHANGED
data/lib/mooset.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mooset
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandru Keszeg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gitlab
|
@@ -141,29 +141,28 @@ files:
|
|
141
141
|
- lib/mooset/application.rb
|
142
142
|
- lib/mooset/configuration.rb
|
143
143
|
- lib/mooset/endpoints.rb
|
144
|
-
- lib/mooset/endpoints/console_logger.rb
|
145
144
|
- lib/mooset/endpoints/endpoint.rb
|
145
|
+
- lib/mooset/endpoints/findable.rb
|
146
146
|
- lib/mooset/endpoints/gitlab.rb
|
147
147
|
- lib/mooset/endpoints/gitlab/group.rb
|
148
148
|
- lib/mooset/endpoints/gitlab/group_search.rb
|
149
|
+
- lib/mooset/endpoints/gitlab/paginate.rb
|
149
150
|
- lib/mooset/endpoints/gitlab/user.rb
|
150
151
|
- lib/mooset/endpoints/gitlab/user_search.rb
|
151
152
|
- lib/mooset/endpoints/ldap.rb
|
152
153
|
- lib/mooset/endpoints/ldap/group.rb
|
153
|
-
- lib/mooset/endpoints/ldap/
|
154
|
+
- lib/mooset/endpoints/ldap/ldap_search.rb
|
155
|
+
- lib/mooset/endpoints/ldap/ou.rb
|
154
156
|
- lib/mooset/endpoints/ldap/user.rb
|
155
|
-
- lib/mooset/endpoints/ldap/user_search.rb
|
156
157
|
- lib/mooset/endpoints/null.rb
|
157
158
|
- lib/mooset/models/group.rb
|
158
159
|
- lib/mooset/models/user.rb
|
159
160
|
- lib/mooset/monads.rb
|
160
161
|
- lib/mooset/resource.rb
|
161
|
-
- lib/mooset/storage.rb
|
162
162
|
- lib/mooset/storage/memory.rb
|
163
|
-
- lib/mooset/
|
163
|
+
- lib/mooset/synchronize_group.rb
|
164
164
|
- lib/mooset/version.rb
|
165
165
|
- mooset.gemspec
|
166
|
-
- spec/mooset/endpoints/gitlab_spec.rb
|
167
166
|
- spec/mooset/endpoints/ldap_spec.rb
|
168
167
|
- spec/spec_helper.rb
|
169
168
|
homepage: ''
|
@@ -191,6 +190,5 @@ signing_key:
|
|
191
190
|
specification_version: 4
|
192
191
|
summary: A Ruby library and client for user migration.
|
193
192
|
test_files:
|
194
|
-
- spec/mooset/endpoints/gitlab_spec.rb
|
195
193
|
- spec/mooset/endpoints/ldap_spec.rb
|
196
194
|
- spec/spec_helper.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Mooset
|
2
|
-
module Endpoints
|
3
|
-
class Ldap
|
4
|
-
class GroupSearch
|
5
|
-
GROUP_FILTER = "(objectClass=group)"
|
6
|
-
|
7
|
-
attr_reader :endpoint
|
8
|
-
|
9
|
-
def initialize(endpoint)
|
10
|
-
@endpoint = endpoint
|
11
|
-
end
|
12
|
-
|
13
|
-
def query(filter = GROUP_FILTER, base: endpoint.treebase)
|
14
|
-
connection.search(base: base, filter: filter).collect do |object|
|
15
|
-
Group.build(endpoint.endpoint_name, object)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def all
|
20
|
-
query(GROUP_FILTER)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def connection
|
26
|
-
@endpoint.connection
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Mooset
|
2
|
-
module Endpoints
|
3
|
-
class Ldap
|
4
|
-
class UserSearch
|
5
|
-
USER_FILTER = "(objectClass=person)"
|
6
|
-
|
7
|
-
attr_reader :endpoint
|
8
|
-
|
9
|
-
def initialize(endpoint)
|
10
|
-
@endpoint = endpoint
|
11
|
-
end
|
12
|
-
|
13
|
-
def query(filter = USER_FILTER, base: endpoint.treebase)
|
14
|
-
connection.search(base: base, filter: filter).collect do |object|
|
15
|
-
User.build(endpoint.endpoint_name, object)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def all
|
20
|
-
query(USER_FILTER)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def connection
|
26
|
-
@endpoint.connection
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/mooset/storage.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Mooset::Endpoints::Gitlab do
|
4
|
-
let(:storage) { double(exists?: false) }
|
5
|
-
let(:connection) { double }
|
6
|
-
let(:command) { Mooset::Endpoints::Gitlab.new(:gitlab, connection: connection, storage: storage) }
|
7
|
-
|
8
|
-
describe '#write' do
|
9
|
-
let(:user) do
|
10
|
-
double({
|
11
|
-
email: 'email',
|
12
|
-
extern_uid: '1',
|
13
|
-
username: 'username',
|
14
|
-
provider: 'ldap',
|
15
|
-
})
|
16
|
-
end
|
17
|
-
|
18
|
-
it "calls the create user api" do
|
19
|
-
expect(connection).to receive(:create_user).with(user.email, anything,{
|
20
|
-
extern_uid: user.extern_uid,
|
21
|
-
username: user.username,
|
22
|
-
provider: 'ldap',
|
23
|
-
})
|
24
|
-
|
25
|
-
command.write(user)
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'when the user is already imported' do
|
29
|
-
let(:storage) { double }
|
30
|
-
|
31
|
-
it "doesn't create duplicate users" do
|
32
|
-
expect(storage).to receive(:exists?).with(user).and_return(true)
|
33
|
-
expect(connection).not_to receive(:create_user)
|
34
|
-
|
35
|
-
command.write(user)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|