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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c1dd100f51b3643d324c7003d9a7ee5be2c2cf0
4
- data.tar.gz: 050188451cc9fc0a22c32c86036d3d55a665ea38
3
+ metadata.gz: 006161edeef876748ef7483011278a0a26f4098d
4
+ data.tar.gz: d93d1a0d851946612246a14b03e694a8743ed29c
5
5
  SHA512:
6
- metadata.gz: 3b01c6cf1a52ba47895c6e2f01eb3b31bc60fc4340b9e6d9078830b26121f10eb74a0e93e06c0337cd215519d78e41d509e248425c0409af472c6339c8b2f139
7
- data.tar.gz: 681efd27a6ed58b68b3fd352612854367c9bb54c54cdc9e4e3b3a9c7d8414e8f4b38c0de34aafdac718895998e4a09ac385ff7f1eb1b6b95e5e35d45dd783158
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, :null, {
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)))'
@@ -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, *args)
8
- Mooset.define_singleton_method(endpoint_name) do
9
- Mooset::Endpoints::Endpoint.create(factory, endpoint_name, *args)
10
- end
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 synchronize_users(from:, to:, **opts)
18
- connections << { from: from, to: to, opts: opts }
32
+ def synchronize_group(from:, to:, **opts)
33
+ operations << Mooset::SynchronizeGroups.new(endpoints[from], endpoints[to], opts)
19
34
  end
20
35
 
21
- def connections
22
- @connection ||= []
36
+ def operations
37
+ @operations ||= []
23
38
  end
24
39
 
25
40
  def run!
26
- connections.each do |event|
27
- from = instances[event[:from]]
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.read_config
53
- s.run!
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
- attr_reader :endpoint_name
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, endpoint_name, *args)
36
- descendants[name].new(endpoint_name, *args)
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
- def self.build(endpoint_name, group)
16
+ finders [:gitlab_id, :name]
17
+
18
+ def self.build(endpoint, group)
16
19
  new(
17
- endpoint_name: endpoint_name,
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.memberof(id)
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
- page = 1
13
- objects = []
15
+ return to_enum(:all) unless block_given?
14
16
 
15
- while (o = connection.groups(page: page)).length > 0 do
16
- objects += o
17
- page += 1
18
- end
17
+ paginate ->(page){ connection.groups(page: page) }, ->(object){ yield Group.build(endpoint, object) }
18
+ end
19
19
 
20
- objects.collect do |object|
21
- Group.build(endpoint.endpoint_name, object)
22
- end
20
+ finder :all do |_, opts = {}|
21
+ all
23
22
  end
24
23
 
25
- def find(id)
26
- Group.build(endpoint.endpoint_name, connection.group(id))
24
+ finder :id do |id, opts = {}|
25
+ Group.build(endpoint, connection.group(id))
27
26
  end
28
27
 
29
- def members(id)
30
- page = 1
31
- objects = []
28
+ finder :gitlab_id do |gitlab_id, opts = {}|
29
+ find(id: gitlab_id)
30
+ end
32
31
 
33
- while (o = connection.group_members(id, page: page)).length > 0 do
34
- objects += o
35
- page += 1
36
- end
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
- objects.collect do |object|
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.endpoint_name, connection.create_group(name, path))
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
- def self.build(endpoint_name, user)
11
+ finders [:gitlab_id, :ldap_id, :email, :username]
12
+
13
+ def self.build(endpoint, user)
10
14
  self.new(
11
- endpoint_name: endpoint_name,
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
- page = 1
13
- objects = []
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
- while (o = connection.users(page: page)).length > 0 do
16
- objects += o
17
- page += 1
18
- end
20
+ def alll
21
+ @alll ||= all.to_a
22
+ end
19
23
 
20
- objects.collect do |object|
21
- User.build(endpoint.endpoint_name, object)
22
- end
24
+ finder :id do |id, opts = {}|
25
+ User.build(endpoint, connection.user(id))
23
26
  end
24
27
 
25
- def find(id)
26
- User.build(endpoint.endpoint_name, connection.user(id))
28
+ finder :gitlab_id do |gitlab_id, opts = {}|
29
+ find(id: gitlab_id)
27
30
  end
28
31
 
29
- def memberof(id)
30
- page = 1
31
- objects = []
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
- while (o = connection.group_members(id, page: page)).length > 0 do
34
- objects += o
35
- page += 1
36
- end
57
+ def group_members(id, &block)
58
+ return to_enum(:group_members, id) unless block_given?
37
59
 
38
- objects.collect do |object|
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
- attribute :storage, Object, default: Proc.new {
17
- Storage::Memory.new(name)
18
- }
19
-
20
- def users
21
- @users ||= UserSearch.new(self)
16
+ resource :users do
17
+ UserSearch.new(self)
22
18
  end
23
19
 
24
- def groups
25
- @groups ||= GroupSearch.new(self)
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(endpoint_name, params)
9
+ def self.build(endpoint, params)
8
10
  group = Optional.new(params)
9
11
  new(
10
- endpoint_name: endpoint_name,
11
- id: group[:dn].value,
12
- name: group[:cn].first.value,
13
- member: group[:member].within do |users|
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 self.users_from(endpoint_name, users)
20
- users.within do |user|
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
@@ -0,0 +1,12 @@
1
+ module Mooset
2
+ module Endpoints
3
+ class Ldap
4
+ class Ou < Group
5
+ def members
6
+ endpoint.users.query('(&(objectClass=user)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))', base: dn)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -41,26 +41,21 @@ module Mooset
41
41
  end
42
42
 
43
43
  class User < Models::User
44
- attribute :provider, String, default: "ldap"
44
+ finders [:dn, :username, :email]
45
45
 
46
- def self.groups_from(endpoint_name, groups)
47
- groups.within do |group|
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(endpoint_name, params)
49
+ def self.build(endpoint, params)
53
50
  user = Optional.new(params)
54
51
 
55
52
  self.new(
56
- endpoint_name: endpoint_name,
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
- def users(query = USER_FILTER)
29
- UserSearch.new(self)
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
- def groups(query = GROUP_FILTER)
45
- GroupSearch.new(self)
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
- def users(query)
5
- [OpenStruct.new]
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
- def groups(query)
9
- []
50
+ resource :groups do
51
+ G.new
10
52
  end
11
53
  end
12
54
  end
@@ -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/user_search'
11
- require 'mooset/endpoints/ldap/group_search'
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
@@ -2,15 +2,29 @@ module Mooset
2
2
  class Resource
3
3
  include Virtus.model
4
4
 
5
- attribute :raw
6
- attribute :endpoint_name
5
+ attr_reader :endpoint
7
6
 
8
- def endpoint
9
- Mooset.public_send(endpoint_name)
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
@@ -1,3 +1,3 @@
1
1
  module Mooset
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/mooset.rb CHANGED
@@ -10,6 +10,5 @@ require "mooset/models/user"
10
10
  require "mooset/models/group"
11
11
 
12
12
  require "mooset/endpoints"
13
- require "mooset/storage/memory"
14
13
  require "mooset/application"
15
- require "mooset/synchronize_users"
14
+ require "mooset/synchronize_group"
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.2
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-15 00:00:00.000000000 Z
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/group_search.rb
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/synchronize_users.rb
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,10 +0,0 @@
1
- module Mooset
2
- module Endpoints
3
- class ConsoleLogger < Endpoint
4
- def write(user)
5
- p user
6
- end
7
- end
8
- end
9
- end
10
-
@@ -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
@@ -1,6 +0,0 @@
1
- require 'mooset/storage/memory'
2
-
3
- module Mooset
4
- module Storage
5
- end
6
- end
@@ -1,9 +0,0 @@
1
- module Mooset
2
- class SynchronizeUsers
3
- def self.call(from, to, opts)
4
- from.users(opts[:query]).each do |user|
5
- to.write(user)
6
- end
7
- end
8
- end
9
- end
@@ -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