fradium 0.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7ce71d5bd193a02708e7df237def67eaea5c5f9be61b550af5a65ca834ede942
4
+ data.tar.gz: 7d72e9d9c41dc3f96988a3bba3ae7474e4f783c318e7a65ffb6dc130d86aa947
5
+ SHA512:
6
+ metadata.gz: 3fe0709bfb196128e913d4225967735bb67ae4c2763d4bc6137ed9ea30c0875edc11291a6168c42f5a9a9b1fa01590260e8f100fc8ab173f0cf01a00f7510122
7
+ data.tar.gz: 2f7c921c15bf3a55ab5f5f26a5786448de55c628c9d78c12689146919fcea32bf139e0fd8e39804a8bb5f593b3dbc882ccd75940d482c20ebc6c5595aca0537f
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # editor's temporary files
14
+ *.sw?
15
+ *~
16
+
17
+ # built gem
18
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.0
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in fradium.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fradium (0.1.2)
5
+ mysql2 (~> 0.5)
6
+ sequel (~> 5.23)
7
+ sqlite3 (~> 1.4)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ coderay (1.1.2)
13
+ diff-lcs (1.3)
14
+ method_source (0.9.2)
15
+ mysql2 (0.5.2)
16
+ pry (0.12.2)
17
+ coderay (~> 1.1.0)
18
+ method_source (~> 0.9.0)
19
+ rake (10.5.0)
20
+ rspec (3.8.0)
21
+ rspec-core (~> 3.8.0)
22
+ rspec-expectations (~> 3.8.0)
23
+ rspec-mocks (~> 3.8.0)
24
+ rspec-core (3.8.2)
25
+ rspec-support (~> 3.8.0)
26
+ rspec-expectations (3.8.4)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.8.0)
29
+ rspec-mocks (3.8.1)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.8.0)
32
+ rspec-support (3.8.2)
33
+ sequel (5.24.0)
34
+ sqlite3 (1.4.1)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ bundler (~> 1.16)
41
+ fradium!
42
+ pry (~> 0.12)
43
+ rake (~> 10.0)
44
+ rspec (~> 3.0)
45
+
46
+ BUNDLED WITH
47
+ 1.17.2
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ (The MIT License)
2
+
3
+ Copyright (C) 2019 Koichiro Iwao <meta@vmeta.jp>
4
+ Copyright (C) 2019 HAW International, Inc.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject
12
+ to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Fradium - FreeRADIUS User Manager
2
+
3
+ Fradium comes from **F**ree**RADIU**S **U**ser **M**anager. Quick and easy tool to manage user database of FreeRADIUS.
4
+
5
+ ## License
6
+ This software is licensed under the MIT license.
7
+
8
+ ## Installation
9
+
10
+ $ gem install fradium
11
+
12
+ ## Usage
13
+
14
+ ### Configuration
15
+
16
+ First of all, create a confiuration file called `.fradium.yaml` in your home directory and specify information needed to your RADIUS database. You can define multiple configuration sets called *profile*.
17
+
18
+ Supported databases are MySQL and MariaDB via `mysql2` adapter so far. It should be work with SQLite or PostgreSQL but still experimental.
19
+
20
+ ```
21
+ default: # default profile
22
+ adapter: mysql2
23
+ host: radius.mysql.example.com
24
+ username: root
25
+ password:
26
+ database: radius
27
+
28
+ staging:
29
+ adapter: mysql2
30
+ host: radius.mysql.example.com
31
+ username: root
32
+ password:
33
+ database: radius_staging
34
+ ```
35
+
36
+ Profiles can be choose by `--profile` option. Specify like `--profile=targetprofile`. If not specified, profile named `default` will be refered by default.
37
+
38
+ ### Further usage
39
+
40
+ It would be easy to use. Running `fradium` without any options will show the usage.
41
+
42
+ ```
43
+ usage:
44
+ exe/fradium [--profile=profile] subcommand ...
45
+
46
+ subcommands as follows:
47
+ create <username> # create new user with password
48
+ show <username> # show password for username
49
+ showall # show all users
50
+ showvalid # show valid(not expired) users
51
+ showexpired # show expired users
52
+ expire <username> # expire the user right now
53
+ unexpire <username> # unexpire the user
54
+ setexpire <username> <expiry date> # set expiry date (date must be parseable by Time#parse)
55
+ modify <username> # generate new password for username
56
+ dbconsole # enter database console
57
+ ```
58
+
59
+ ## Development
60
+
61
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
62
+
63
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
64
+
65
+ ## Contributing
66
+
67
+ Bug reports and pull requests are welcome on GitHub at https://github.com/metalefty/fradium.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "fradium"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
12
+
13
+ #require "irb"
14
+ #IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/fradium ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yaml'
4
+ require_relative '../lib/fradium'
5
+
6
+ def config_file_not_found
7
+ print <<"EOD"
8
+ #{File.basename $0}: config file not found
9
+
10
+ Put ~/.fradium.yaml to define MySQL database to connect.
11
+ An Example of .fradium.yaml as follows.
12
+
13
+ -------------------------------------------------------------------------------
14
+
15
+ default: # default profile
16
+ adapter: mysql2
17
+ host: localhost
18
+ username: root
19
+ password: mysqlpassword
20
+ database: radius
21
+
22
+ staging: # if you want to define another profile
23
+ adapter: mysql2
24
+ host: localhost
25
+ username: root
26
+ password: mysqlpassword
27
+ database: radius_staging
28
+
29
+ -------------------------------------------------------------------------------
30
+ EOD
31
+ exit
32
+ end
33
+
34
+ def show_help
35
+ print <<"EOD"
36
+ usage:
37
+ #{File.basename $0} [--profile=profile] subcommand ...
38
+
39
+ subcommands as follows:
40
+ create <username> # create new user with password
41
+ show <username> # show password for username
42
+ showall # show all users
43
+ showvalid # show valid(not expired) users
44
+ showexpired # show expired users
45
+ expire <username> # expire the user right now
46
+ unexpire <username> # unexpire the user
47
+ setexpire <username> <expiry date> # set expiry date (date must be parseable by Time#parse)
48
+ modify <username> # generate new password for username
49
+ dbconsole # enter database console
50
+ EOD
51
+ exit
52
+ end
53
+
54
+ def show_user(username)
55
+ user = @f.find_user(username).first
56
+ printf "%s %s\n", user[:username], user[:value]
57
+ end
58
+
59
+ # main routine starts here:
60
+ begin
61
+ @config = YAML.load_file(ENV['HOME'] + '/.fradium.yaml')
62
+ rescue Errno::ENOENT, Errno::EACCESS
63
+ config_file_not_found
64
+ end
65
+
66
+ profile = 'default'
67
+ if ARGV[0]&.start_with?('--profile')
68
+ profile = ARGV[0].split(/=/,2)[1]
69
+ ARGV.shift
70
+ end
71
+
72
+ @f = Fradium.new(@config[profile])
73
+
74
+ case ARGV[0]
75
+
76
+ when 'create'
77
+ show_help if ARGV[1]&.empty?
78
+ @f.create_user(ARGV[1])
79
+ show_user(ARGV[1])
80
+
81
+ when 'dbconsole'
82
+ @f.dbconsole
83
+
84
+ when 'show'
85
+ show_user(ARGV[1])
86
+
87
+ when 'showall'
88
+ @f.all_users.map{|e| e[:username]}.each do |e|
89
+ puts e
90
+ end
91
+
92
+ when 'showvalid'
93
+ (@f.all_users.map{|e| e[:username]} - @f.expired_users.map{|e| e[:username]}).each do |e|
94
+ puts e
95
+ end
96
+
97
+ when 'showexpired'
98
+ @f.expired_users.map{|e| e[:username]}.each do |e|
99
+ puts e
100
+ end
101
+
102
+ when 'expire'
103
+ @f.expire_user(ARGV[1])
104
+
105
+ when 'unexpire'
106
+ @f.unexpire_user(ARGV[1])
107
+
108
+ when 'setexpire'
109
+ show_help if ARGV[2].nil? || ARGV[2].empty?
110
+ expiry_date = Time.parse(ARGV[2])
111
+ @f.set_expiration(ARGV[1], expiry_date)
112
+
113
+ when 'modify' # change user password
114
+ @f.modify_user(ARGV[1])
115
+ show_user(ARGV[1])
116
+
117
+ else # unknown subcommand
118
+ show_help
119
+ end
data/fradium.gemspec ADDED
@@ -0,0 +1,43 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "fradium/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fradium"
8
+ spec.version = Fradium::VERSION
9
+ spec.authors = ["Koichiro IWAO"]
10
+ spec.email = ["meta@vmeta.jp"]
11
+
12
+ spec.summary = %q{fradium - FreeRADIUS User Manager}
13
+ spec.description = %q{Quick User Management Tool for FreeRADIUS}
14
+ spec.homepage = "https://github.com/metalefty/fradium"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.required_ruby_version = '>= 2.5.0'
34
+
35
+ spec.add_development_dependency "bundler", "~> 1.16"
36
+ spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rspec", "~> 3.0"
38
+ spec.add_development_dependency 'pry', '~> 0.12'
39
+
40
+ spec.add_dependency 'mysql2', '~> 0.5'
41
+ spec.add_dependency 'sqlite3', '~> 1.4'
42
+ spec.add_dependency 'sequel', '~> 5.23'
43
+ end
@@ -0,0 +1,3 @@
1
+ class Fradium
2
+ VERSION = "0.1.2"
3
+ end
data/lib/fradium.rb ADDED
@@ -0,0 +1,132 @@
1
+ require "fradium/version"
2
+ require 'securerandom'
3
+ require 'sequel'
4
+ require 'time'
5
+
6
+ class Fradium
7
+ class UserAlreadyExistsError < StandardError; end
8
+ class UserNotFoundError < StandardError; end
9
+ class UsernameEmptyError < StandardError; end
10
+ class CorruptedUserDatabaseError < StandardError; end
11
+
12
+ def initialize(params)
13
+ @params = params
14
+
15
+ case @params['adapter']
16
+ when 'sqlite'
17
+ @sequel = Sequel.connect("sqlite://#{@params['file']}")
18
+ else
19
+ @sequel = Sequel.connect(@params)
20
+ end
21
+ end
22
+
23
+ def user_exists?(username)
24
+ find_user(username).count > 0
25
+ end
26
+
27
+ def all_users
28
+ @sequel[:radcheck].where{attribute.like '%-Password'}
29
+ end
30
+
31
+ def create_user(username)
32
+ raise UsernameEmptyError if username&.empty?
33
+ raise UserAlreadyExistsError if user_exists?(username)
34
+ password = Fradium.generate_random_password
35
+
36
+ @sequel[:radcheck].insert(username: username,
37
+ attribute: 'Cleartext-Password',
38
+ op: ':=',
39
+ value: password)
40
+ end
41
+
42
+ def find_user(username)
43
+ raise UsernameEmptyError if username&.empty?
44
+ reult = @sequel[:radcheck].where(username: username).where{attribute.like '%-Password'}
45
+ end
46
+
47
+ def modify_user(username)
48
+ raise UsernameEmptyError if username&.empty?
49
+ raise UserNotFoundError unless user_exists?(username)
50
+ password = Fradium.generate_random_password
51
+
52
+ target = find_user(username)
53
+ raise CorruptedUserDatabaseError if target.count > 1
54
+ target.update(value: password, attribute: 'Cleartext-Password')
55
+ end
56
+
57
+ def expired_users
58
+ now = Time.now
59
+ # a little bit redundant but for consistency
60
+ id = @sequel[:radcheck].where(attribute: 'Expiration').collect{|e| e[:id] if Time.now > Time.parse(e[:value])}
61
+ @sequel[:radcheck].where(id: id)
62
+ end
63
+
64
+ def expire_user(username)
65
+ set_expiration(username, Time.now)
66
+ end
67
+
68
+ def unexpire_user(username)
69
+ raise UsernameEmptyError if username&.empty?
70
+ raise UserNotFoundError unless user_exists?(username)
71
+ @sequel[:radcheck].where(username: username, attribute: 'Expiration').delete
72
+ end
73
+
74
+ def is_expired?(username)
75
+ expiration_date = query_expiration(username)&.fetch('value')
76
+ return false if expiration_date.nil? || expiration_date.empty? # if expiration info not found, not expired yet
77
+ Time.now > Time.parse(expiration_date)
78
+ end
79
+
80
+ def set_expiration(username, expiration_date)
81
+ expiration_info = query_expiration(username)
82
+
83
+ value = ''
84
+ if expiration_date.instance_of?(Time)
85
+ value = expiration_date.strftime("%d %b %Y %H:%M:%S")
86
+ else
87
+ value = Time.parse(expiration_date).strftime("%d %b %Y %H:%M:%S")
88
+ end
89
+
90
+ if expiration_info.nil? # add new entry
91
+ @sequel[:radcheck].insert(username: username,
92
+ attribute: 'Expiration',
93
+ op: ':=',
94
+ value: value)
95
+ else # update existing entry
96
+ expiration_info.update(value: value)
97
+ end
98
+ end
99
+
100
+ def dbconsole
101
+ # I know this is not safe.
102
+ Kernel.exec({'MYSQL_PWD' => @params['password']},
103
+ 'mysql',
104
+ "--pager=less -SF",
105
+ "--user=#{@params['username']}",
106
+ "--host=#{@params['host']}" ,
107
+ "#{@params['database']}")
108
+ end
109
+
110
+ def self.generate_random_password(length=10)
111
+ r = SecureRandom.urlsafe_base64.delete('-_')
112
+ while r.length < length
113
+ r << SecureRandom.urlsafe_base64.delete('-_')
114
+ end
115
+ r[0..length-1]
116
+ end
117
+
118
+ #private
119
+
120
+ def query_expiration(username)
121
+ raise UsernameEmptyError if username&.empty?
122
+ raise UserNotFoundError unless user_exists?(username)
123
+
124
+ r = @sequel[:radcheck].where(username: username, attribute: 'Expiration')
125
+
126
+ raise CorruptedUserDatabaseError if r.count > 1
127
+ return nil if r.count == 0 # if no expiration info found
128
+ return nil if r&.first[:value]&.empty?
129
+
130
+ r
131
+ end
132
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fradium
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Koichiro IWAO
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-09-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mysql2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.5'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.4'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sequel
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.23'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.23'
111
+ description: Quick User Management Tool for FreeRADIUS
112
+ email:
113
+ - meta@vmeta.jp
114
+ executables:
115
+ - fradium
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - LICENSE
125
+ - README.md
126
+ - Rakefile
127
+ - bin/console
128
+ - bin/setup
129
+ - exe/fradium
130
+ - fradium.gemspec
131
+ - lib/fradium.rb
132
+ - lib/fradium/version.rb
133
+ homepage: https://github.com/metalefty/fradium
134
+ licenses:
135
+ - MIT
136
+ metadata:
137
+ allowed_push_host: https://rubygems.org
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 2.5.0
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubygems_version: 3.0.3
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: fradium - FreeRADIUS User Manager
157
+ test_files: []