jgrouper 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +12 -0
- data/bin/jgrouper-diff +68 -0
- data/bin/jgrouper-export +2 -3
- data/bin/jgrouper-grant +1 -1
- data/bin/jgrouper-revoke +107 -0
- data/jgrouper.gemspec +2 -0
- data/lib/jgrouper/export_file_diff.rb +49 -0
- data/lib/jgrouper/export_file_entry.rb +99 -0
- data/lib/jgrouper/export_file_reader.rb +65 -0
- data/lib/jgrouper/exporter.rb +105 -8
- data/lib/jgrouper/field.rb +17 -11
- data/lib/jgrouper/group.rb +33 -64
- data/lib/jgrouper/group_type.rb +11 -23
- data/lib/jgrouper/member.rb +1 -1
- data/lib/jgrouper/source.rb +6 -13
- data/lib/jgrouper/stem.rb +26 -35
- data/lib/jgrouper/subject.rb +9 -9
- data/lib/jgrouper/version.rb +1 -1
- data/lib/jgrouper.rb +8 -9
- metadata +73 -34
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.
|
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
|
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> <
|
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
|
data/bin/jgrouper-revoke
ADDED
@@ -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
|
+
|
data/lib/jgrouper/exporter.rb
CHANGED
@@ -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
|
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
|
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(
|
60
|
-
log "exporting stem #{stem.name} ..."
|
61
|
-
p.call stem
|
62
|
-
stem
|
63
|
-
stem.
|
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
|
data/lib/jgrouper/field.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
49
|
-
to_hash.
|
54
|
+
def to_json
|
55
|
+
to_hash.to_json
|
50
56
|
end
|
51
57
|
|
52
58
|
end
|
data/lib/jgrouper/group.rb
CHANGED
@@ -50,74 +50,47 @@ module JGrouper # :nodoc:
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
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
|
-
|
61
|
-
|
62
|
-
'
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
79
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
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
|
|
data/lib/jgrouper/group_type.rb
CHANGED
@@ -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
|
-
|
77
|
-
|
78
|
-
|
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
|
82
|
-
to_hash.
|
69
|
+
def to_json
|
70
|
+
to_hash.to_json
|
83
71
|
end
|
84
72
|
|
85
73
|
end
|
data/lib/jgrouper/member.rb
CHANGED
@@ -23,7 +23,7 @@ module JGrouper # :nodoc:
|
|
23
23
|
#
|
24
24
|
def self.find(uuid)
|
25
25
|
begin
|
26
|
-
m =
|
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
|
data/lib/jgrouper/source.rb
CHANGED
@@ -40,22 +40,15 @@ module JGrouper # :nodoc:
|
|
40
40
|
|
41
41
|
def to_hash
|
42
42
|
{
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
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 =
|
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 =
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
113
|
-
|
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
|
-
|
121
|
-
|
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
|
-
|
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
|
|
data/lib/jgrouper/subject.rb
CHANGED
@@ -23,7 +23,7 @@ module JGrouper # :nodoc:
|
|
23
23
|
#
|
24
24
|
def self.find(id_or_identifier)
|
25
25
|
begin
|
26
|
-
subj =
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
|
data/lib/jgrouper/version.rb
CHANGED
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
|
-
|
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
|
-
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:
|
12
|
+
date: 2014-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
|
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:
|
22
|
-
|
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:
|
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
|
-
|
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
|
-
|
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.
|
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: []
|