jgrouper 0.5.0 → 0.6.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/HISTORY.md CHANGED
@@ -1,6 +1,18 @@
1
1
  JGrouper History
2
2
  ================
3
3
 
4
+ 2014-01-10 JGrouper v0.6.0
5
+ -------------------------
6
+ * Add `bin/jgrouper-diff`
7
+ * Add `bin/jgrouper-revoke`
8
+ * Add `JGrouper::ExportFileDiff`
9
+ * Add `JGrouper::ExportFileEntry`
10
+ * Add `JGrouper::ExportFileReader`
11
+ * Add `JGrouper::Group.revoke()`
12
+ * Add `JGrouper::Stem.revoke()`
13
+ * Update `JGrouper::Export` and `bin/jgrouper-export` to export to JSON
14
+
15
+
4
16
  2013-08-15 JGrouper v0.5.0
5
17
  --------------------------
6
18
  * Add `JGrouper.start_root_session()`
data/bin/jgrouper-diff ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env jruby
2
+
3
+ require 'jgrouper/export_file_entry'
4
+ require 'jgrouper/export_file_reader'
5
+
6
+ require 'optparse'
7
+
8
+ #
9
+ # TODO Optionally key on attribute other than UUID?
10
+ #
11
+
12
+
13
+ opts = OptionParser.new do |opts|
14
+ opts.banner = "USAGE: #{ File.basename(__FILE__) } [-h]"
15
+
16
+ opts.on_tail('-h', '--help', "Show this message") do
17
+ puts opts
18
+ exit
19
+ end
20
+ opts.on_tail( '-v', '--[no-]verbose', 'Enable verbose mode [DEFAULT: no]' ) do |value|
21
+ exporter.verbose = value
22
+ end
23
+ end.parse!
24
+
25
+
26
+ JGrouper::ExportFileReader.new(ARGV.shift) do |src|
27
+ JGrouper::ExportFileReader.new(ARGV.shift) do |dst|
28
+ loop do
29
+
30
+ src.next do |json|
31
+ entry = JGrouper::ExportFileEntry.new json
32
+ next if entry.metadata?
33
+
34
+ if dst.include?(entry)
35
+ diff = entry.diff dst[entry]
36
+ puts diff.to_json if diff.different? # Modified
37
+ dst.delete(entry)
38
+ else
39
+ src << entry
40
+ end
41
+ end unless src.done?
42
+
43
+
44
+ dst.next do |json|
45
+ entry = JGrouper::ExportFileEntry.new json
46
+ next if entry.metadata?
47
+
48
+ if src.include?( entry )
49
+ diff = src[entry].diff entry
50
+ puts diff.to_json if diff.different? # Modified
51
+ src.delete(entry)
52
+ else
53
+ dst << entry
54
+ end
55
+ end unless dst.done?
56
+
57
+ if dst.done? && src.done?
58
+ src.each { |_| puts _.diff( JGrouper::ExportFileEntry.new ).to_json } # Delete
59
+ dst.each { |_| puts JGrouper::ExportFileEntry.new.diff(_).to_json } # Add
60
+ break
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+
67
+ # vim: syntax=ruby
68
+
data/bin/jgrouper-export CHANGED
@@ -4,7 +4,6 @@ require 'jgrouper'
4
4
  require 'jgrouper/exporter'
5
5
  require 'optparse'
6
6
  require 'thread'
7
- require 'yaml'
8
7
 
9
8
 
10
9
  JGrouper::Exporter.new do |exporter|
@@ -44,14 +43,14 @@ JGrouper::Exporter.new do |exporter|
44
43
  JGrouper.start_root_session
45
44
 
46
45
  # TODO GzipWriter?
47
- fn = File.join directory, 'jgrouper-export.yaml'
46
+ fn = File.join directory, 'jgrouper-export.json'
48
47
  File.open( fn, 'w' ) do |fh|
49
48
  fh.flock File::LOCK_EX
50
49
 
51
50
  loop do
52
51
  while queue.size > 0
53
52
  value = queue.pop
54
- fh.puts value.to_yaml
53
+ fh.puts value
55
54
  end
56
55
  if done && queue.empty?
57
56
  break
data/bin/jgrouper-grant CHANGED
@@ -78,7 +78,7 @@ end
78
78
  MyApp.new do |app|
79
79
 
80
80
  opts = OptionParser.new do |opts|
81
- opts.banner = "USAGE: #{ File.basename(__FILE__) } [options] <stem-or-group> <privilege> <subject>"
81
+ opts.banner = "USAGE: #{ File.basename(__FILE__) } [options] <stem-or-group> <admin|create|optin|optout|read|stem|view> <subject>"
82
82
  opts.on('-R', '--[no-]recurse', 'Recursively grant privileges [DEFAULT: no]') do |recurse|
83
83
  app.recurse = recurse
84
84
  end
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env jruby
2
+
3
+ require 'jgrouper'
4
+ require 'optparse'
5
+
6
+
7
+ class MyApp
8
+
9
+ attr_accessor :recurse, :verbose
10
+
11
+ def initialize
12
+ @recurse = false
13
+ @verbose = false
14
+ yield self if block_given?
15
+ self
16
+ end
17
+
18
+ def revoke(stem_or_group, privilege, subject)
19
+ raise 'ERROR: stem-or-group is nil' if stem_or_group.nil?
20
+ raise 'ERROR: privilege is nil' if stem_or_group.nil?
21
+ raise 'ERROR: subject is nil' if stem_or_group.nil?
22
+
23
+ priv = JGrouper::Privilege.find privilege
24
+ raise "ERROR: could not find privilege: #{privilege}" if priv.nil?
25
+ puts "found privilege: #{priv.to_s}" if verbose?
26
+ subj = JGrouper::Subject.find(subject)
27
+ raise "ERROR: could not find subject: #{subject}" if subj.nil?
28
+ puts "found subject: #{subj.to_s}" if verbose?
29
+
30
+ stem = JGrouper::Stem.find(stem_or_group)
31
+ return revoke_stem(stem, priv, subj) unless stem.nil?
32
+
33
+ group = JGrouper::Group.find(stem_or_group)
34
+ return revoke_group(group, priv, subj) unless group.nil?
35
+
36
+ raise "ERROR: could not find stem-or-group: #{stem_or_group}"
37
+ end
38
+
39
+ def recurse? ; @recurse ; end
40
+ def verbose? ; @verbose ; end
41
+
42
+
43
+ private
44
+
45
+ def revoke_group(group, privilege, subject)
46
+ if privilege.naming?
47
+ warn 'WARNING: cannot revoke naming privilege on group'
48
+ return false
49
+ end
50
+
51
+ puts "revoking privilege #{privilege.name} from subject #{subject} on group #{group.name}" if verbose?
52
+ group.revoke(subject, privilege)
53
+ end
54
+
55
+ def revoke_stem(stem, privilege, subject)
56
+ if privilege.access?
57
+ unless recurse?
58
+ warn 'WARNING: cannot revoke access privilege on stem without specifying -R'
59
+ return false
60
+ end
61
+ stem.groups do |group|
62
+ puts "revoking privilege #{privilege.name} from subject #{subject} on group #{group.name}" if verbose?
63
+ group.revoke(subject, privilege)
64
+ end
65
+ stem.stems { |child| revoke_stem(child, privilege, subject) }
66
+ return
67
+ end
68
+
69
+ puts "revoking privilege #{privilege.name} from subject #{subject} on stem #{stem.name}" if verbose?
70
+ stem.revoke(subject, privilege)
71
+ stem.stems { |child| revoke_stem(child, privilege, subject) } if recurse?
72
+ true
73
+ end
74
+
75
+ end
76
+
77
+
78
+ MyApp.new do |app|
79
+
80
+ opts = OptionParser.new do |opts|
81
+ opts.banner = "USAGE: #{ File.basename(__FILE__) } [options] <stem-or-group> <admin|create|optin|optout|read|stem|view> <subject>"
82
+ opts.on('-R', '--[no-]recurse', 'Recursively revoke privileges [DEFAULT: no]') do |recurse|
83
+ app.recurse = recurse
84
+ end
85
+ opts.on_tail('-h', '--help', 'Show help') do
86
+ puts opts
87
+ exit
88
+ end
89
+ opts.on_tail('-v', '--[no-]verbose', 'Enable verbose mode [DEFAULT: no]') do |verbose|
90
+ app.verbose = verbose
91
+ end
92
+ end.parse!
93
+
94
+ # TODO DRY
95
+ if ENV['GROUPER_HOME']
96
+ JGrouper.home! ENV['GROUPER_HOME']
97
+ else
98
+ warn "ERROR: GROUPER_HOME not set"
99
+ exit 1
100
+ end
101
+
102
+ app.revoke( ARGV.shift, ARGV.shift, ARGV.shift ) or exit 1
103
+
104
+ end
105
+
106
+ # vim: syntax=ruby
107
+
data/jgrouper.gemspec CHANGED
@@ -18,7 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
+ spec.add_dependency 'hashdiff'
21
22
  spec.add_dependency 'jruby-jars', '>= 1.7.3'
23
+ spec.add_dependency 'json'
22
24
 
23
25
  spec.add_development_dependency 'bundler', '~> 1.3'
24
26
  spec.add_development_dependency 'rake'
@@ -0,0 +1,49 @@
1
+ require 'hashdiff'
2
+ require 'json'
3
+
4
+ module JGrouper # :nodoc:
5
+ #
6
+ # = JGrouper::ExportFileDiff - Difference between two JGrouper::ExportFileEntry objects
7
+ #
8
+ # == WARNING
9
+ #
10
+ # The output format is unstable and will change in a future release.
11
+ #
12
+ # == USAGE
13
+ #
14
+ # require 'jgrouper'
15
+ # require 'jgrouper/export_file_diff'
16
+ # require 'jgrouper/export_file_entry'
17
+ #
18
+ # diff = JGrouper::ExportFileDiff JGrouper::ExportFileEntry.new(json), JGrouper::ExportFileEntry.new(json)
19
+ #
20
+ class ExportFileDiff
21
+
22
+ def initialize(src, dst)
23
+ @dst = dst
24
+ @key = dst.key || src.key
25
+ @src = src
26
+ @diff = HashDiff.diff @src.json, @dst.json
27
+ end
28
+
29
+ def different?
30
+ !@diff.empty?
31
+ end
32
+
33
+ def to_s
34
+ { key: @key, diff: @diff }.inspect
35
+ end
36
+
37
+ def to_hash
38
+ return {} unless different?
39
+ return { entry: @key, changes: @diff }
40
+ end
41
+
42
+ def to_json
43
+ to_hash.to_json
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,99 @@
1
+ require 'jgrouper/export_file_diff'
2
+ require 'json'
3
+
4
+ module JGrouper # :nodoc:
5
+ #
6
+ # = JGrouper::ExportFileEntry - Entry from JGrouper::Exporter file
7
+ #
8
+ # == USAGE
9
+ #
10
+ # require 'jgrouper'
11
+ # require 'jgrouper/export_file_entry'
12
+ # require 'jgrouper/export_file_reader'
13
+ #
14
+ # JGrouper::ExportFileReader.new(file_name) do |reader|
15
+ # reader.next { |json| entry = JGrouper::ExportFileEntry.new json }
16
+ # end
17
+ #
18
+ class ExportFileEntry
19
+
20
+ attr_reader :key, :kind, :json
21
+
22
+ def initialize( json = {} )
23
+ @json = json
24
+ @kind = @json['kind']
25
+
26
+ @key = nil
27
+ @name = nil
28
+ @stem = nil
29
+ @subject = nil
30
+ @uuid = nil # Or equivalent ...
31
+
32
+ case @kind
33
+ when 'admins', 'members', 'optins', 'optouts', 'readers', 'viewers', 'updaters'
34
+ @group = @json['group']
35
+ @subject = @json['subject']
36
+ @key = [ @kind, @group['uuid'], @subject ]
37
+ when 'composite'
38
+ @group = @json['group']
39
+ @key = [ @kind, @group['uuid'] ]
40
+ when 'creators', 'stemmers'
41
+ @stem = @json['stem']
42
+ @subject = @json['subject']
43
+ @key = [ @kind, @stem['uuid'], @subject ]
44
+ when 'field'
45
+ @name = @json['name']
46
+ @uuid = @json['uuid']
47
+ @key = [ @kind, @uuid ]
48
+ when 'group'
49
+ %w( create_subject create_time modify_subject modify_time ).each { |_| @json.delete _ }
50
+ @name = @json['name']
51
+ @uuid = @json['uuid']
52
+ @key = [ @kind, @uuid ]
53
+ when 'group_attributes'
54
+ @group = @json['group']
55
+ @name = @json['name']
56
+ @key = [ @kind, @group['uuid'], @name ]
57
+ when 'group_type'
58
+ @name = @json['name']
59
+ @uuid = @json['uuid']
60
+ @key = [ @kind, @uuid ]
61
+ when 'metadata'
62
+ @key = @kind
63
+ when 'source'
64
+ @name = @json['name']
65
+ @uuid = @json['id'] # Effectively ...
66
+ @key = [ @kind, @uuid ]
67
+ when 'stem'
68
+ %w( create_subject create_time modify_subject modify_time ).each { |_| @json.delete _ }
69
+ @name = @json['name']
70
+ @uuid = @json['uuid']
71
+ @key = [ @kind, @uuid ]
72
+ else
73
+ warn "invalid entry type: #{ @kind } - #{ @json.inspect }" unless @json.empty?
74
+ end
75
+ end
76
+
77
+ def ==(other)
78
+ self.class == other.class && self.kind == other.kind && self.key == other.key
79
+ end
80
+
81
+ alias eql? ==
82
+
83
+ def diff(other)
84
+ JGrouper::ExportFileDiff.new self, other
85
+ end
86
+
87
+ def hash
88
+ raise "nil @key - #{ @self.inspect }" if @key.nil?
89
+ @key.hash
90
+ end
91
+
92
+ def metadata?
93
+ 'metadata' == @kind
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
@@ -0,0 +1,65 @@
1
+ require 'json'
2
+
3
+ module JGrouper # :nodoc:
4
+ #
5
+ # = JGrouper::ExportFileReader - Read output file from JGrouper::Exporter
6
+ #
7
+ # == USAGE
8
+ #
9
+ # require 'jgrouper'
10
+ # require 'jgrouper/export_file_reader'
11
+ #
12
+ # JGrouper::ExportFileReader.new(file_name) do |reader|
13
+ # reader.next { |json| ... }
14
+ # end
15
+ #
16
+ class ExportFileReader
17
+ include Enumerable
18
+
19
+ def initialize(fn)
20
+ @done = false
21
+ @entries = {}
22
+ @fn = fn
23
+
24
+ @fh = File.open @fn, 'r'
25
+ yield self
26
+ @fh.close
27
+ end
28
+
29
+ def <<(entry)
30
+ @entries[ entry ] = entry
31
+ end
32
+
33
+ def [](entry)
34
+ @entries[entry]
35
+ end
36
+
37
+ def delete(entry)
38
+ @entries.delete(entry)
39
+ end
40
+
41
+ def done?
42
+ @done
43
+ end
44
+
45
+ def each(&block)
46
+ @entries.values.each(&block)
47
+ end
48
+
49
+ def include?(entry)
50
+ @entries.include?(entry)
51
+ end
52
+
53
+ def next
54
+ return if done?
55
+ if @fh.eof?
56
+ @done = true
57
+ return
58
+ end
59
+ yield JSON.parse( @fh.gets )
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
@@ -1,3 +1,4 @@
1
+ require 'json'
1
2
 
2
3
  module JGrouper # :nodoc:
3
4
  #
@@ -8,12 +9,14 @@ module JGrouper # :nodoc:
8
9
  # require 'jgrouper'
9
10
  # require 'jgrouper/exporter'
10
11
  #
11
- # JGrouper::Exporter do |exporter|
12
+ # JGrouper::Exporter.new do |exporter|
12
13
  # exporter.export 'stem:to:export', lambda { |_| puts _.to_yaml }
13
14
  # end
14
15
  #
15
16
  class Exporter
16
17
 
18
+ EXPORT_VERSION = 1
19
+
17
20
  attr_writer :verbose
18
21
 
19
22
  def initialize
@@ -34,8 +37,10 @@ module JGrouper # :nodoc:
34
37
  # TODO Multiple readers?
35
38
  txt = stem.root? ? 'root stem' : "stem #{stem.name}"
36
39
  log "exporting #{txt} ..."
40
+ export_metadata params[:block]
37
41
  if stem.root? # TODO Configurable?
38
42
  export_group_types params[:block]
43
+ export_fields params[:block]
39
44
  export_sources params[:block]
40
45
  end
41
46
  export_stem stem, params[:block]
@@ -43,28 +48,120 @@ module JGrouper # :nodoc:
43
48
 
44
49
  end
45
50
 
51
+ # Export fields
52
+ def export_fields(p)
53
+ log 'exporting group fields ...'
54
+ JGrouper::Field.all.each { |_| p.call _.to_json }
55
+ log 'exporting group fields: done'
56
+ end
57
+
46
58
  # Export group types.
47
59
  def export_group_types(p)
48
60
  log 'exporting group types ...'
49
- p.call JGrouper::GroupType
61
+ JGrouper::GroupType.all.each { |_| p.call _.to_json }
62
+ log 'exporting group types: done'
63
+ end
64
+
65
+ # Export metadata
66
+ def export_metadata(p)
67
+ log 'exporting metadata ...'
68
+ p.call( { kind: 'metadata',
69
+ export_version: EXPORT_VERSION,
70
+ jgrouper_version: JGrouper::VERSION,
71
+ hostname: ENV['HOSTNAME'],
72
+ ruby_engine: RUBY_ENGINE,
73
+ ruby_platform: RUBY_PLATFORM,
74
+ ruby_version: RUBY_VERSION,
75
+ start_time: Time.now.to_datetime.rfc3339
76
+ }.to_json
77
+ )
78
+ log 'exporting metadata: done'
50
79
  end
51
80
 
52
81
  # Export subject sources.
53
82
  def export_sources(p)
54
83
  log 'exporting subject sources ...'
55
- p.call JGrouper::Source
84
+ JGrouper::Source.all.each { |source| p.call source.to_json }
85
+ log 'exporting subject sources: done'
56
86
  end
57
87
 
58
88
  # Export stem and childen.
59
- def export_stem( stem, p )
60
- log "exporting stem #{stem.name} ..."
61
- p.call stem
62
- stem.groups { |child| p.call child }
63
- stem.stems { |child| export_stem(child, p) }
89
+ def export_stem(stem, p)
90
+ log "exporting stem #{stem.name} ..." # TODO Debug ... unless root?!
91
+ p.call stem.to_json
92
+ export_stem_privileges(stem, p)
93
+ stem.groups { |child| export_group child, p }
94
+ stem.stems { |child| export_stem child, p }
95
+ log "exporting stem #{stem.name}: done" # TODO Debug ... unless root?!
64
96
  end
65
97
 
66
98
 
67
99
  private
100
+
101
+ def export_group(group, p)
102
+ p.call group.to_json
103
+ export_group_attributes group, p
104
+ export_group_privileges group, p
105
+ export_group_members group, p
106
+ end
107
+
108
+ def export_group_attributes(group, p)
109
+ group.get_attributes_map(false).each do |k, v|
110
+ p.call( { kind: 'group_attributes',
111
+ group: { name: group.name, uuid: group.uuid },
112
+ name: k,
113
+ value: v.get_value
114
+ }.to_json
115
+ )
116
+ end
117
+ end
118
+
119
+ def export_group_members(group, p)
120
+ c = group.get_composite false
121
+ if c
122
+ left = c.get_left_group
123
+ right = c.get_right_group
124
+ p.call( { kind: 'composite',
125
+ group: { name: group.name, uuid: group.uuid },
126
+ type: c.get_type.get_name,
127
+ left: { name: left.get_name, uuid: left.get_uuid },
128
+ right: { name: right.get_name, uuid: right.get_name }
129
+ }.to_json
130
+ )
131
+ else
132
+ group.get_immediate_members.each do |_|
133
+ p.call( { kind: 'members',
134
+ group: { name: group.name, uuid: group.uuid },
135
+ subject: JGrouper::Subject.new( _.get_subject ).to_hash
136
+ }.to_json
137
+ )
138
+ end
139
+ end
140
+ end
141
+
142
+ def export_group_privileges(group, p)
143
+ [ :admins, :optins, :optouts, :readers, :updaters, :viewers ].each do |privilege|
144
+ group.send(privilege).each do |_|
145
+ p.call( { kind: privilege,
146
+ group: { name: group.name, uuid: group.uuid },
147
+ subject: JGrouper::Subject.new(_).to_hash
148
+ }.to_json
149
+ )
150
+ end
151
+ end
152
+ end
153
+
154
+ def export_stem_privileges(stem, p)
155
+ [ :creators, :stemmers ].each do |privilege|
156
+ stem.send(privilege).each do |_|
157
+ p.call( { kind: privilege,
158
+ stem: { name: stem.name, uuid: stem.uuid },
159
+ subject: JGrouper::Subject.new(_).to_hash
160
+ }.to_json
161
+ )
162
+ end
163
+ end
164
+ end
68
165
 
69
166
  # TODO Use Logger...
70
167
  # TODO DRY
@@ -18,6 +18,13 @@ module JGrouper # :nodoc:
18
18
  self
19
19
  end
20
20
 
21
+ #
22
+ # Find all fields.
23
+ #
24
+ def self.all
25
+ JFieldFinder.find_all.collect { |_| self.new _ }
26
+ end
27
+
21
28
  #
22
29
  # For passing methods on to Grouper Field object.
23
30
  #
@@ -33,20 +40,19 @@ module JGrouper # :nodoc:
33
40
 
34
41
  def to_hash
35
42
  {
36
- 'kind' => 'field',
37
- 'name' => @obj.get_name,
38
- 'uuid' => @obj.get_uuid,
39
- 'nullable' => @obj.get_is_nullable,
40
- 'required' => @obj.get_required,
41
- 'privilege' => {
42
- 'read' => @obj.get_read_privilege,
43
- 'write' => @obj.get_write_privilege
44
- }
43
+ kind: 'field',
44
+ group_type: { name: @obj.get_group_type.get_name, uuid: @obj.get_group_type.get_uuid },
45
+ name: @obj.get_name,
46
+ uuid: @obj.get_uuid,
47
+ nullable: @obj.get_is_nullable,
48
+ required: @obj.get_required,
49
+ read_privilege: @obj.get_read_privilege,
50
+ write_privilege: @obj.get_write_privilege
45
51
  }
46
52
  end
47
53
 
48
- def to_yaml
49
- to_hash.to_yaml
54
+ def to_json
55
+ to_hash.to_json
50
56
  end
51
57
 
52
58
  end
@@ -50,74 +50,47 @@ module JGrouper # :nodoc:
50
50
  end
51
51
  end
52
52
 
53
- def to_hash
54
- begin
55
- mod_subj = JGrouper::Subject.new( @obj.get_modify_subject )
56
- rescue edu.internet2.middleware.subject.SubjectNotFoundException
57
- mod_subj = nil
58
- end
53
+ def revoke(subject, privilege)
54
+ @obj.revokePriv subject.to_grouper, privilege.to_grouper, false
55
+ end
59
56
 
60
- hash = {
61
- 'kind' => 'group',
62
- 'uuid' => @obj.get_uuid,
63
- 'name' => @obj.get_name,
64
- 'display_name' => @obj.get_display_name,
65
- 'extension' => @obj.get_extension,
66
- 'display_extension' => @obj.get_display_extension,
67
- 'description' => @obj.get_description,
68
- 'parent' => {
69
- 'name' => @obj.get_parent_stem_name,
70
- 'uuid' => @obj.get_parent_uuid,
71
- },
72
- 'create' => {
73
- 'subject' => JGrouper::Subject.new( @obj.get_create_subject ).to_hash,
74
- 'time' => Time.at( @obj.get_create_time_long / 1000 ).to_datetime.rfc3339
75
- }
57
+ def to_hash
58
+ h = {
59
+ kind: 'group',
60
+ uuid: @obj.get_uuid,
61
+ name: @obj.get_name,
62
+ display_name: @obj.get_display_name,
63
+ extension: @obj.get_extension,
64
+ display_extension: @obj.get_display_extension,
65
+ create_subject: JGrouper::Subject.new( @obj.get_create_subject ).to_hash,
66
+ create_time: Time.at( @obj.get_create_time_long / 1000 ).to_datetime.rfc3339,
67
+ parent: { name: @obj.get_parent_stem.get_name, uuid: @obj.get_parent_stem.get_uuid }
76
68
  }
77
69
 
78
- begin
79
- mod_subj = JGrouper::Subject.new( @obj.get_modify_subject )
80
- hash['modify'] = {
81
- 'subject' => mod_subj ? mod_subj.to_hash : nil,
82
- 'time' => Time.at( @obj.get_modify_time_long / 1000 ).to_datetime.rfc3339
83
- }
84
- rescue
70
+ unless @obj.get_alternate_names.empty?
71
+ h[:alternate_names] = @obj.get_alternate_names.collect(&:to_s)
85
72
  end
86
-
87
- # TODO Ugly
88
- unless @obj.get_admins.empty? &&
89
- @obj.get_optins.empty? &&
90
- @obj.get_optouts.empty? &&
91
- @obj.get_readers.empty? &&
92
- @obj.get_updaters.empty &&
93
- @obj.get_viewers.empty?
94
- hash['privileges'] = {}
95
- hash['privileges']['admin'] = @obj.get_admins.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_admins.empty?
96
- hash['privileges']['optin'] = @obj.get_optins.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_optins.empty?
97
- hash['privileges']['optout'] = @obj.get_optouts.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_optouts.empty?
98
- hash['privileges']['read'] = @obj.get_readers.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_readers.empty?
99
- hash['privileges']['update'] = @obj.get_updaters.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_updaters.empty?
100
- hash['privileges']['view'] = @obj.get_viewers.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_viewers.empty?
73
+ unless @obj.get_description.empty?
74
+ h[:description] = @obj.get_description
75
+ end
76
+ unless @obj.get_removable_types.empty?
77
+ h[:group_types] = @obj.get_removable_types.collect { |_| { name: _.get_name, uuid: _.get_uuid } }
78
+ end
79
+ if 'role' == @obj.get_type_of_group.to_s
80
+ h[:role] = true
101
81
  end
102
82
 
103
- hash['types'] = @obj.get_removable_types.collect { |_| { 'name' => _.get_name, 'uuid' => _.get_uuid } } unless @obj.get_removable_types.empty?
104
- hash['attributes'] = @obj.get_attributes_map(false).inject({}) { |h, (k,v)| h[k] = v.get_value ; h } unless @obj.get_attributes_map(false).empty?
105
- hash['alternate_names'] = @obj.get_alternate_names.collect { |_| _ } unless @obj.get_alternate_names.empty?
106
-
107
- hash['role'] = 'role' if 'role' == @obj.get_type_of_group.to_string
108
-
109
- composite = @obj.get_composite(false)
110
- if composite
111
- hash['composite'] = {
112
- 'type' => composite.get_type.get_name,
113
- 'left' => { 'name' => composite.get_left_group.get_name, 'uuid' => composite.get_left_group.get_uuid },
114
- 'right' => { 'name' => composite.get_right_group.get_name, 'uuid' => composite.get_right_group.get_uuid }
115
- }
116
- else
117
- hash['members'] = @obj.get_immediate_members.collect { |_| JGrouper::Subject.new( _.get_subject ).to_hash } unless @obj.get_immediate_members.empty?
83
+ begin
84
+ h[:modify_subject] = JGrouper::Subject.new( @obj.get_modify_subject ).to_hash
85
+ h[:modify_time] = Time.at( @obj.get_modify_time_long / 1000 ).to_datetime.rfc3339
86
+ rescue
118
87
  end
119
88
 
120
- hash
89
+ h
90
+ end
91
+
92
+ def to_json
93
+ to_hash.to_json
121
94
  end
122
95
 
123
96
  def to_s
@@ -125,10 +98,6 @@ module JGrouper # :nodoc:
125
98
  %w( name display_name uuid ).collect { |k| "#{k}=#{ self.send(k) }" }.to_csv.chomp
126
99
  end
127
100
 
128
- def to_yaml
129
- to_hash.to_yaml
130
- end
131
-
132
101
  end
133
102
  end
134
103
 
@@ -54,32 +54,20 @@ module JGrouper # :nodoc:
54
54
  end
55
55
 
56
56
  def to_hash
57
- hash = {
58
- 'kind' => 'group_type',
59
- 'name' => @obj.get_name,
60
- 'uuid' => @obj.get_uuid,
61
- 'assignable' => @obj.get_is_assignable,
62
- 'internal' => @obj.get_is_internal,
63
- 'create' => {
64
- 'uuid' => @obj.get_creator_uuid,
65
- 'time' => Time.at( @obj.get_create_time / 1000 ).to_datetime.rfc3339
66
- }
67
- }
68
- unless @obj.get_fields.empty?
69
- hash['fields'] = @obj.get_fields.collect { |_| JGrouper::Field.new(_).to_hash }
70
- end
71
- hash
72
- end
73
-
74
- def self.to_yaml
75
57
  {
76
- 'kind' => 'group_types',
77
- 'group_types' => all.collect { |_| self.new(_).to_hash }
78
- }.to_yaml
58
+ kind: 'group_type',
59
+ name: @obj.get_name,
60
+ uuid: @obj.get_uuid,
61
+ assignable: @obj.get_is_assignable,
62
+ internal: @obj.get_is_internal,
63
+ create_time: Time.at( @obj.get_create_time / 1000 ).to_datetime.rfc3339,
64
+ create_uuid: @obj.get_creator_uuid,
65
+ fields: @obj.get_fields.collect { |f| { name: f.get_name, uuid: f.get_uuid } }
66
+ }
79
67
  end
80
68
 
81
- def to_yaml
82
- to_hash.to_yaml
69
+ def to_json
70
+ to_hash.to_json
83
71
  end
84
72
 
85
73
  end
@@ -23,7 +23,7 @@ module JGrouper # :nodoc:
23
23
  #
24
24
  def self.find(uuid)
25
25
  begin
26
- m = MemberFinder.find_by_uuid JGrouper.start_root_session, uuid, false
26
+ m = JMemberFinder.find_by_uuid JGrouper.start_root_session, uuid, false
27
27
  rescue => e
28
28
  warn "JGrouper::Member.find(#{uuid}) => #{e}"
29
29
  end
@@ -40,22 +40,15 @@ module JGrouper # :nodoc:
40
40
 
41
41
  def to_hash
42
42
  {
43
- 'kind' => 'source',
44
- 'id' => @obj.get_id,
45
- 'name' => @obj.get_name,
46
- 'init_params' => @obj.get_init_params.inject({}) { |h, (k,v)| h[k] = v ; h }
43
+ kind: 'source',
44
+ id: @obj.get_id,
45
+ name: @obj.get_name,
46
+ init_params: @obj.get_init_params.each { |k,v| { name: k, value: v }.collect }
47
47
  }
48
48
  end
49
49
 
50
- def self.to_yaml
51
- {
52
- 'kind' => 'sources',
53
- 'sources' => all.collect { |_| self.new(_).to_hash }
54
- }.to_yaml
55
- end
56
-
57
- def to_yaml
58
- to_hash.to_yaml
50
+ def to_json
51
+ to_hash.to_json
59
52
  end
60
53
 
61
54
  end
data/lib/jgrouper/stem.rb CHANGED
@@ -24,7 +24,7 @@ module JGrouper # :nodoc:
24
24
  #
25
25
  def self.find(name)
26
26
  begin
27
- obj = StemFinder.find_by_name JGrouper.start_root_session, name, false
27
+ obj = JStemFinder.find_by_name JGrouper.start_root_session, name, false
28
28
  rescue => e
29
29
  warn "JGrouper::Group.find(#{name}) => #{e}"
30
30
  end
@@ -62,11 +62,15 @@ module JGrouper # :nodoc:
62
62
  end
63
63
  end
64
64
 
65
+ def revoke(subject, privilege)
66
+ @obj.revokePriv subject.to_grouper, privilege.to_grouper, false
67
+ end
68
+
65
69
  #
66
70
  # Find Grouper root stem. Returns +JGrouper::Stem+ or +nil+.
67
71
  #
68
72
  def self.root
69
- obj = StemFinder.find_root_stem JGrouper.start_root_session
73
+ obj = JStemFinder.find_root_stem JGrouper.start_root_session
70
74
  return nil if obj.nil?
71
75
  stem = self.new obj
72
76
  yield stem if block_given?
@@ -92,43 +96,34 @@ module JGrouper # :nodoc:
92
96
  end
93
97
 
94
98
  def to_hash
95
- hash = {
96
- 'kind' => 'stem',
97
- 'uuid' => @obj.get_uuid,
98
- 'name' => @obj.get_name,
99
- 'display_name' => @obj.get_display_name,
100
- 'extension' => @obj.get_extension,
101
- 'display_extension' => @obj.get_display_extension
99
+ h = {
100
+ kind: 'stem',
101
+ uuid: @obj.get_uuid,
102
+ name: @obj.get_name,
103
+ display_name: @obj.get_display_name,
104
+ extension: @obj.get_extension,
105
+ display_extension: @obj.get_display_extension,
106
+ create_subject: JGrouper::Subject.new( @obj.get_create_subject ).to_hash,
107
+ create_time: Time.at( @obj.get_create_time_long / 1000 ).to_datetime.rfc3339
102
108
  }
103
109
 
104
- hash['description'] = @obj.get_description unless @obj.get_description.empty?
105
-
106
- hash['create'] = {
107
- 'subject' => JGrouper::Subject.new( @obj.get_create_subject ).to_hash,
108
- 'time' => Time.at( @obj.get_create_time_long / 1000 ).to_datetime.rfc3339
109
- }
110
+ h[:description] = @obj.get_description unless @obj.get_description.empty?
111
+ unless root?
112
+ parent = @obj.get_parent_stem
113
+ h[:parent] = { name: parent.get_name, uuid: parent.get_uuid }
114
+ end
110
115
 
111
116
  begin
112
- mod_subj = JGrouper::Subject.new( @obj.get_modify_subject )
113
- hash['modify'] = {
114
- 'subject' => mod_subj ? mod_subj.to_hash : nil,
115
- 'time' => Time.at( @obj.get_modify_time_long / 1000 ).to_datetime.rfc3339
116
- }
117
+ h[:modify_subject] = JGrouper::Subject.new( @obj.get_modify_subject ).to_hash
118
+ h[:modify_time] = Time.at( @obj.get_modify_time_long / 1000 ).to_datetime.rfc3339
117
119
  rescue
118
120
  end
119
121
 
120
- unless @obj.get_creators.empty? && @obj.get_stemmers.empty?
121
- hash['privileges'] = {}
122
- hash['privileges']['create'] = @obj.get_creators.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_creators.empty?
123
- hash['privileges']['stem'] = @obj.get_stemmers.collect { |_| JGrouper::Subject.new(_).to_hash } unless @obj.get_stemmers.empty?
124
- end
125
-
126
- hash['stems'] = @obj.child_stems.collect { |_| { 'name' => _.get_name, 'uuid' => _.get_uuid } } unless @obj.child_stems.empty?
127
- hash['groups'] = @obj.child_groups.collect { |_| { 'name' => _.get_name, 'uuid' => _.get_uuid } } unless @obj.child_groups.empty?
128
-
129
- hash['parent'] = { 'name' => @obj.get_parent_stem.get_name, 'uuid' => @obj.get_parent_uuid } unless root?
122
+ h
123
+ end
130
124
 
131
- hash
125
+ def to_json
126
+ to_hash.to_json
132
127
  end
133
128
 
134
129
  def to_s
@@ -136,10 +131,6 @@ module JGrouper # :nodoc:
136
131
  %w( name display_name uuid ).collect { |k| "#{k}=#{ self.send(k) }" }.to_csv.chomp
137
132
  end
138
133
 
139
- def to_yaml
140
- to_hash.to_yaml
141
- end
142
-
143
134
  end
144
135
  end
145
136
 
@@ -23,7 +23,7 @@ module JGrouper # :nodoc:
23
23
  #
24
24
  def self.find(id_or_identifier)
25
25
  begin
26
- subj = SubjectFinder.find_by_id_or_identifier id_or_identifier, false
26
+ subj = JSubjectFinder.find_by_id_or_identifier id_or_identifier, false
27
27
  rescue => e
28
28
  warn "JGrouper::Subject.find(#{id_or_identifier}) => #{e}"
29
29
  end
@@ -50,22 +50,22 @@ module JGrouper # :nodoc:
50
50
 
51
51
  def to_hash
52
52
  {
53
- 'kind' => 'subject',
54
- 'id' => @obj.get_id,
55
- 'source' => @obj.get_source_id,
56
- 'type' => @obj.get_type_name
53
+ kind: 'subject',
54
+ id: @obj.get_id,
55
+ source: @obj.get_source_id,
56
+ type: @obj.get_type_name
57
57
  }
58
58
  end
59
59
 
60
+ def to_json
61
+ to_hash.to_json
62
+ end
63
+
60
64
  def to_s
61
65
  return nil if @obj.nil?
62
66
  %w( id type_name source_id name ).collect { |k| "#{k}=#{ self.send(k) }" }.to_csv.chomp
63
67
  end
64
68
 
65
- def to_yaml
66
- to_hash.to_yaml
67
- end
68
-
69
69
  end
70
70
  end
71
71
 
@@ -1,4 +1,4 @@
1
1
  module JGrouper
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
4
4
 
data/lib/jgrouper.rb CHANGED
@@ -10,6 +10,7 @@ require 'jgrouper/stem'
10
10
  require 'jgrouper/subject'
11
11
  require 'jgrouper/version'
12
12
 
13
+
13
14
  #
14
15
  # = JGrouper - JRuby wrapper around the Internet2 Grouper API
15
16
  #
@@ -161,20 +162,18 @@ module JGrouper
161
162
  $CLASSPATH << File.join( path, 'conf' )
162
163
  $CLASSPATH << File.join( path, 'dist', 'lib', 'grouper.jar' )
163
164
 
164
- %w( edu.internet2.middleware.subject.SubjectNotFoundException
165
- edu.internet2.middleware.grouper.GrouperSession
166
- edu.internet2.middleware.grouper.MemberFinder
167
- edu.internet2.middleware.grouper.StemFinder
168
- edu.internet2.middleware.grouper.SubjectFinder
169
- ).each { |klass| java_import klass }
170
-
171
- # TODO Do this for everything?
172
165
  %w(
173
166
  edu.internet2.middleware.grouper.Field
167
+ edu.internet2.middleware.grouper.FieldFinder
174
168
  edu.internet2.middleware.grouper.GroupFinder
169
+ edu.internet2.middleware.grouper.GrouperSession
175
170
  edu.internet2.middleware.grouper.GroupTypeFinder
171
+ edu.internet2.middleware.grouper.MemberFinder
176
172
  edu.internet2.middleware.grouper.privs.Privilege
177
173
  edu.internet2.middleware.subject.provider.SourceManager
174
+ edu.internet2.middleware.grouper.StemFinder
175
+ edu.internet2.middleware.grouper.SubjectFinder
176
+ edu.internet2.middleware.subject.SubjectNotFoundException
178
177
  ).each do |klass|
179
178
  java_import klass do |pkg, cls| "J#{cls}"; end
180
179
  end
@@ -183,7 +182,7 @@ module JGrouper
183
182
  # TODO Block method?
184
183
  def self.start_root_session
185
184
  # TODO Block method?
186
- GrouperSession.start_root_session
185
+ JGrouperSession.start_root_session
187
186
  end
188
187
 
189
188
  end
metadata CHANGED
@@ -1,87 +1,121 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jgrouper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
5
- prerelease:
4
+ version: 0.6.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - blair christensen
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-15 00:00:00.000000000 Z
12
+ date: 2014-01-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: jruby-jars
16
- requirement: !ruby/object:Gem::Requirement
15
+ name: hashdiff
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
17
21
  none: false
22
+ requirement: !ruby/object:Gem::Requirement
18
23
  requirements:
19
- - - ! '>='
24
+ - - '>='
20
25
  - !ruby/object:Gem::Version
21
- version: 1.7.3
22
- type: :runtime
26
+ version: '0'
27
+ none: false
23
28
  prerelease: false
29
+ type: :runtime
30
+ - !ruby/object:Gem::Dependency
31
+ name: jruby-jars
24
32
  version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: 1.7.3
25
37
  none: false
38
+ requirement: !ruby/object:Gem::Requirement
26
39
  requirements:
27
- - - ! '>='
40
+ - - '>='
28
41
  - !ruby/object:Gem::Version
29
42
  version: 1.7.3
43
+ none: false
44
+ prerelease: false
45
+ type: :runtime
30
46
  - !ruby/object:Gem::Dependency
31
- name: bundler
47
+ name: json
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ none: false
32
54
  requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
33
59
  none: false
60
+ prerelease: false
61
+ type: :runtime
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ version_requirements: !ruby/object:Gem::Requirement
34
65
  requirements:
35
66
  - - ~>
36
67
  - !ruby/object:Gem::Version
37
68
  version: '1.3'
38
- type: :development
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
69
  none: false
70
+ requirement: !ruby/object:Gem::Requirement
42
71
  requirements:
43
72
  - - ~>
44
73
  - !ruby/object:Gem::Version
45
74
  version: '1.3'
75
+ none: false
76
+ prerelease: false
77
+ type: :development
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: rake
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
80
+ version_requirements: !ruby/object:Gem::Requirement
50
81
  requirements:
51
- - - ! '>='
82
+ - - '>='
52
83
  - !ruby/object:Gem::Version
53
84
  version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
85
  none: false
86
+ requirement: !ruby/object:Gem::Requirement
58
87
  requirements:
59
- - - ! '>='
88
+ - - '>='
60
89
  - !ruby/object:Gem::Version
61
90
  version: '0'
91
+ none: false
92
+ prerelease: false
93
+ type: :development
62
94
  - !ruby/object:Gem::Dependency
63
95
  name: rdoc-readme
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
96
+ version_requirements: !ruby/object:Gem::Requirement
66
97
  requirements:
67
98
  - - ~>
68
99
  - !ruby/object:Gem::Version
69
100
  version: 0.1.2
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
101
  none: false
102
+ requirement: !ruby/object:Gem::Requirement
74
103
  requirements:
75
104
  - - ~>
76
105
  - !ruby/object:Gem::Version
77
106
  version: 0.1.2
107
+ none: false
108
+ prerelease: false
109
+ type: :development
78
110
  description: JRuby wrapper around the Internet2 Grouper API
79
111
  email:
80
112
  - blair.christensen@gmail.com
81
113
  executables:
82
114
  - jgrouper-audit-archiver
115
+ - jgrouper-diff
83
116
  - jgrouper-export
84
117
  - jgrouper-grant
118
+ - jgrouper-revoke
85
119
  extensions: []
86
120
  extra_rdoc_files: []
87
121
  files:
@@ -94,11 +128,16 @@ files:
94
128
  - Rakefile
95
129
  - TODO.md
96
130
  - bin/jgrouper-audit-archiver
131
+ - bin/jgrouper-diff
97
132
  - bin/jgrouper-export
98
133
  - bin/jgrouper-grant
134
+ - bin/jgrouper-revoke
99
135
  - jgrouper.gemspec
100
136
  - lib/jgrouper.rb
101
137
  - lib/jgrouper/audit_archiver.rb
138
+ - lib/jgrouper/export_file_diff.rb
139
+ - lib/jgrouper/export_file_entry.rb
140
+ - lib/jgrouper/export_file_reader.rb
102
141
  - lib/jgrouper/exporter.rb
103
142
  - lib/jgrouper/field.rb
104
143
  - lib/jgrouper/group.rb
@@ -112,26 +151,26 @@ files:
112
151
  homepage: https://github.com/blairc/jgrouper/
113
152
  licenses:
114
153
  - MIT
115
- post_install_message:
154
+ post_install_message:
116
155
  rdoc_options: []
117
156
  require_paths:
118
157
  - lib
119
158
  required_ruby_version: !ruby/object:Gem::Requirement
120
- none: false
121
159
  requirements:
122
- - - ! '>='
160
+ - - '>='
123
161
  - !ruby/object:Gem::Version
124
162
  version: '0'
125
- required_rubygems_version: !ruby/object:Gem::Requirement
126
163
  none: false
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
165
  requirements:
128
- - - ! '>='
166
+ - - '>='
129
167
  - !ruby/object:Gem::Version
130
168
  version: '0'
169
+ none: false
131
170
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 1.8.23
134
- signing_key:
171
+ rubyforge_project:
172
+ rubygems_version: 1.8.24
173
+ signing_key:
135
174
  specification_version: 3
136
175
  summary: JRuby wrapper around the Internet2 Grouper API
137
176
  test_files: []