tok_access 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6aec725ecefd64e58d1fafa64d9450372b0fb705
4
+ data.tar.gz: 2200ef5494e6da6552f6ff8469a0251ade70a559
5
+ SHA512:
6
+ metadata.gz: 40ed63785ecef8c0b50810ee00729e9e856c9de2f67b9dac6e2dd327c1b7b1291bc73c5a82bab07dedd951840b265abe38fba4fd5349dcf41c1cc0021bdc6e9f
7
+ data.tar.gz: 8608c7e8ad2c4599ba9b410c3961cba4b7249d45bf3bd3b0eccc1fa3976e5dd77e20870afd9f7174dae4ab0ddb0c34e409794cf24129cfb7b8ef1da9c20fed6a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Yonga
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # TokAccess
2
+ Handle authentication of your users using tokens.
3
+ Every 'tokified' user will have a association named
4
+ toks.
5
+
6
+ A tok is an object that consist of two attributes: token, devise_token.
7
+
8
+ You should use the devise_token to identify the user devices
9
+ in which the user has logged in and the token to authenticate the
10
+ user request.
11
+
12
+ TokAccess use bcrypt has_secure_password and has_secure_token methods to handle the authentication process and tokens generation
13
+
14
+ ## Usage
15
+
16
+ #### Imagine you have a User model and a mobile app in which a user want to sign up.
17
+
18
+ ```ruby
19
+ # somewhere in a controller that handle the users registration
20
+
21
+ def sign_up
22
+ user = User.new(user_params)
23
+ if user.save
24
+ # if the user is saved, an associated tok is created
25
+ # and you can access that tok using the following methods
26
+ token = user.get_token
27
+ devise_token = user.get_devise_token
28
+ # return the tokens to the front-end.
29
+ else
30
+ # code if the user can't be saved
31
+ end
32
+ end
33
+ ```
34
+ #### So, now the user is logged in one device and start browsing the app. How to identify the user that sign up previously?
35
+
36
+ ```ruby
37
+ # somewhere in your code, probably in you ApplicationController
38
+ # let's say that you are sending a token in a header named
39
+ # APP_TOKEN
40
+
41
+ def current_user
42
+ @current_user ||= User.validate_access(token: request.headers["HTTP_APP_TOKEN"])
43
+ end
44
+
45
+ def user_signed_in?
46
+ !current_user.nil?
47
+ end
48
+
49
+ def current_token
50
+ current_user ? current_user.get_token : nil
51
+ end
52
+
53
+ def current_devise_token
54
+ current_user ? current_user.get_devise_token : nil
55
+ end
56
+
57
+ # After 15 minutes, the next user request will refresh the tokens.
58
+ # it is necessary to send the tokens to the front-end again
59
+
60
+ def tokens_refreshed?
61
+ if current_user and current_user.refreshed?
62
+ # Some code that allows you to send the tokens to the front-end
63
+ end
64
+ end
65
+ ```
66
+
67
+
68
+ #### Now the previous user wants to login in a new device
69
+
70
+ ```ruby
71
+ # somewhere in a controller that handle the users sign in
72
+
73
+ def sign_in
74
+ user = User.find_by(email: params[:email])
75
+ if user.tok_auth(params[:password])
76
+ # if the user is authenticated successfully, a new tok is created
77
+ # and you can access that tok using the following methods
78
+ token = user.get_token
79
+ devise_token = user.get_devise_token
80
+ # then you should return to the front-end the tokens.
81
+ else
82
+ # code if the user authentication fails
83
+ end
84
+ end
85
+ ```
86
+
87
+ #### Now the previous user wants to login in an old device
88
+
89
+ ```ruby
90
+ # somewhere in a controller that handle the users sign in
91
+ # let's say that you are sending a devise_token in a header named
92
+ # APP_DEVISE_TOKEN
93
+
94
+ def sign_in
95
+ user = User.find_by(email: params[:email])
96
+ if user.tok_auth(params[:password], request.headers["HTTP_APP_DEVISE_TOKEN"])
97
+ # if the user is authenticated successfully and the tok related to the
98
+ # given devise_token is found, the token and devise_token are regenerated
99
+ # and you can access that tok using the get_token and get_devise_token
100
+ # methods.
101
+ # if the user is authenticated successfully and the tok related to the
102
+ # given devise_token wasn't found, a new tok is created and you can access
103
+ # that tok using the get_token and get_devise_token
104
+ # methods.
105
+ token = user.get_token
106
+ devise_token = user.get_devise_token
107
+ # then you should return to the front-end the tokens.
108
+ else
109
+ # code if the user authentication fails
110
+ end
111
+ end
112
+ ```
113
+
114
+ #### Accessing the toks from the user.
115
+ ```ruby
116
+
117
+ user = User.validate_access(token: request.headers["HTTP_APP_TOKEN"])
118
+ user.toks # UserTok collection.
119
+
120
+ ```
121
+
122
+
123
+ ## Installation
124
+ Add this line to your application's Gemfile:
125
+
126
+ ```ruby
127
+ gem 'tok_access'
128
+ ```
129
+
130
+ And then execute:
131
+ ```bash
132
+ $ bundle
133
+ ```
134
+
135
+ ### Generating models
136
+
137
+ Generating a User model.
138
+
139
+ ```bash
140
+ $ rails g tok_access:model User email:string nickname:string
141
+ ```
142
+ The above command will generate two models: User and UserTok
143
+
144
+ The migration generated to create the User model will add a column named
145
+ password_digest to store the password.
146
+
147
+ #### IMPORTANT: If you already have a User model, the command will generate just the migration to add the password_digest column
148
+
149
+ #### NOTE: You can generate any model to be 'tokified' just pass the name of the model
150
+
151
+ ```bash
152
+ $ rails g tok_access:model Person email:string nickname:string
153
+ ```
154
+ The above command will generate two models: Person and PersonTok
155
+
156
+ #### IMPORTANT: If you use the tok_access:model generator to destroy the model, the Model and ModelTok will be destroyed. It's a better choice to do it manually
157
+
158
+ ```bash
159
+ $ rails d model user
160
+ $ rails d model user_tok
161
+ ```
162
+
163
+ Also, remember to remove the migrations...
164
+
165
+
166
+ ## License
167
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'TokAccess'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+
33
+ task default: :test
@@ -0,0 +1,33 @@
1
+ Description:
2
+ Use this generator to create the models that you want give access through tokens
3
+ It will generate the a migration to add a password_digest attribute to the model.
4
+ If the model does not exist, will generate it.
5
+ Also generates a model to handle the related toks. If your model name
6
+ is User, the associated tok model name will be UserTok.
7
+
8
+ Example:
9
+ rails generate tok_access:model User email:string nickname:string birth:date -f
10
+
11
+ This will be the output:
12
+ create db/migrate/20170913173053_tok_access_create_users.rb
13
+ create app/models/user.rb
14
+ invoke test_unit
15
+ create test/models/user_test.rb
16
+ create test/fixtures/users.yml
17
+ create db/migrate/20170913173054_create_user_toks.rb
18
+ create app/models/user_tok.rb
19
+ invoke test_unit
20
+ insert app/models/user.rb
21
+ insert app/models/user_tok.rb
22
+
23
+ If the model already exists, this will be the output:
24
+ create db/migrate/20170913173229_add_tok_access_to_users.rb
25
+ identical app/models/user.rb
26
+ invoke test_unit
27
+ identical test/models/user_test.rb
28
+ force test/fixtures/users.yml
29
+ create db/migrate/20170913173230_create_user_toks.rb
30
+ create app/models/user_tok.rb
31
+ invoke test_unit
32
+ insert app/models/user.rb
33
+ insert app/models/user_tok.rb
@@ -0,0 +1,48 @@
1
+ require 'generators/tok_access/orm_helper'
2
+ require 'rails/generators/active_record/model/model_generator'
3
+
4
+ module TokAccess
5
+ module Generators
6
+ class ModelGenerator < ActiveRecord::Generators::ModelGenerator
7
+ include TokAccess::Generators::OrmHelper
8
+ source_root File.join(File.dirname(ActiveRecord::Generators::ModelGenerator.instance_method(:create_migration_file).source_location.first), "templates")
9
+
10
+
11
+ def create_migration_file
12
+ return unless options[:migration] && options[:parent].nil?
13
+ attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
14
+ if behavior == :invoke
15
+ if model_exists? or migration_exists?(table_name)
16
+ migration_template "#{__FILE__}/../templates/migration_existing_for.rb", "db/migrate/add_tok_access_to_#{table_name}.rb", migration_version: migration_version
17
+ else
18
+ migration_template "#{__FILE__}/../templates/migration_for.rb", "db/migrate/tok_access_create_#{table_name}.rb", migration_version: migration_version
19
+ end
20
+ end
21
+ if behavior == :revoke
22
+ migration_template "#{__FILE__}/../templates/migration_existing_for.rb", "db/migrate/add_tok_access_to_#{table_name}.rb", migration_version: migration_version
23
+ migration_template "#{__FILE__}/../templates/migration_for.rb", "db/migrate/tok_access_create_#{table_name}.rb", migration_version: migration_version
24
+ end
25
+ end
26
+
27
+ def generate_tok_model
28
+ tok_model_table_name = "#{table_name.singularize}_tok"
29
+ tok_model_class_name = "#{table_name.singularize}_tok".camelize
30
+ if behavior == :invoke
31
+ if !File.exist?(Rails.root.join("app", "models", "#{tok_model_table_name}.rb"))
32
+ invoke "active_record:model", [tok_model_class_name, "token:string","devise_token:string", "object_id:integer"]
33
+ end
34
+ inject_into_class(Rails.root.join("app", "models", "#{table_name.singularize}.rb"), Object.const_get(table_name.singularize.camelize)) do
35
+ %Q{\ttokify\n}
36
+ end
37
+ inject_into_class(Rails.root.join("app", "models", "#{tok_model_table_name}.rb"), Object.const_get(tok_model_class_name)) do
38
+ %Q{\tdefine_toks :#{table_name.singularize}\n}
39
+ end
40
+ end
41
+ if behavior == :revoke
42
+ system "rails d model #{table_name.singularize.camelize}"
43
+ system "rails d model #{tok_model_class_name}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,35 @@
1
+ module TokAccess
2
+ module Generators
3
+ module OrmHelper
4
+
5
+ private
6
+
7
+ def model_exists?
8
+ File.exist?(File.join(destination_root, model_path))
9
+ end
10
+
11
+ def migration_exists?(table_name)
12
+ Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_tok_access_to_#{table_name}.rb$/).first
13
+ end
14
+
15
+ def migration_path
16
+ @migration_path ||= File.join("db", "migrate")
17
+ end
18
+
19
+ def model_path
20
+ @model_path ||= File.join("app", "models", "#{file_path}.rb")
21
+ end
22
+
23
+ def migration_version
24
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
25
+ end
26
+
27
+ def migration_data
28
+ <<-RUBY.strip_heredoc
29
+ t.string :password_digest, null: false, default: ""
30
+ RUBY
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ class AddTokAccessTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+
4
+ change_table :<%= table_name %> do |t|
5
+ <%= migration_data %>
6
+ <% attributes.each do |attribute| %>
7
+ t.<%= attribute.type %> :<%= attribute.name %>
8
+ <% end %>
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ class TokAccessCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+
4
+ create_table :<%= table_name %> do |t|
5
+ <%= migration_data %>
6
+ <% attributes.each do |attribute| %>
7
+ t.<%= attribute.type %> :<%= attribute.name %>
8
+ <% end %>
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,7 @@
1
+ module TokAccess
2
+ module Generators
3
+ class TokAccessGenerator < Rails::Generators::Base
4
+ #namespace "tok_access"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :tok_access do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,135 @@
1
+ module TokAccess
2
+
3
+ module TokAuthenticable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ # before create an tokified object, setup the toks
9
+ before_create :setup_access_tok
10
+
11
+ # Return nil if you haven't authenticated the object
12
+ # using the method #tok_auth or the method #tok_auth failed the
13
+ # authentication process. Otherwise, return the token attribute of one
14
+ # of the associated object toks.
15
+ def get_token
16
+ @_token
17
+ end
18
+
19
+ # Return nil if you haven't authenticated the object
20
+ # using the method #tok_auth or the method #tok_auth failed the
21
+ # authentication process. Otherwise, return the devise_token attribute
22
+ # of one of the associated object toks.
23
+ def get_devise_token
24
+ @_devise_token
25
+ end
26
+
27
+ # Return nil if you haven't use the method TokAccess.validate_access.
28
+ # After the TokAccess.validate_access method is called, if the access was validated
29
+ # successfuly, this method will return true if the token was regenerated, otherwise
30
+ # return nil
31
+ def refreshed?
32
+ @refreshed
33
+ end
34
+
35
+
36
+ # Authenticate the object with the given password .
37
+ # If the authentication process is successful return the object and the
38
+ # methods #get_tok and #get_devise_tok will return the tokens
39
+ # Return nil if the authentication process fails
40
+ # You can pass as a parameter a devise_token. If the object has a tok that
41
+ # match the devise_token given, will regenerate the tok. If you do not
42
+ # pass the devise_token parameter, the method will create a new tok
43
+ # associated with the object. If the object.toks.size is equal to the
44
+ # toks_limit, the method will destroy one of the toks and create a new one
45
+ def tok_auth(password, devise_token = nil )
46
+ if self.authenticate(password)
47
+ generate_access_toks(devise_token)
48
+ return self
49
+ end
50
+ nil
51
+ end
52
+
53
+ # If the object is associated to the tok given the method will return
54
+ # the object and the methods #get_tok and #get_devise_tok will
55
+ # return the tokens. Otherwise return nil
56
+ def provide_access(tok)
57
+ if self.toks.find_by(id: tok.id)
58
+ refresh tok
59
+ set_token tok.token
60
+ set_devise_token tok.devise_token
61
+ return self
62
+ end
63
+ nil
64
+ end
65
+
66
+ private
67
+
68
+ def refresh(tok)
69
+ if tok.updated_at >= 15.minutes.ago
70
+ tok.touch
71
+ @refreshed = true
72
+ end
73
+ end
74
+
75
+ def set_token(token)
76
+ @_token = token
77
+ end
78
+
79
+ def set_devise_token(token)
80
+ @_devise_token = token
81
+ end
82
+
83
+ def setup_access_tok
84
+ self.toks.build()
85
+ end
86
+
87
+ def generate_access_toks(devise_token = nil)
88
+ if !devise_token
89
+ self.toks.order(updated_at: :asc).first.destroy if self.toks.count == TokAccess.config.tokens_limit
90
+ tok = self.toks.create
91
+ else
92
+ tok = self.toks.find_by(devise_token: devise_token)
93
+ tok.regenerate_token if tok
94
+ tok.regenerate_devise_token if tok
95
+ end
96
+ if tok
97
+ @refreshed = true
98
+ set_token tok.token
99
+ set_devise_token tok.devise_token
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ module ClassMethods
106
+
107
+ # object: The object to authenticate
108
+ # password: The password to authenticate the object with
109
+ # if the object is authenticatred successfully, returns the object with
110
+ # => the get_token and get_devise_token methods returning the access
111
+ # => tokens.
112
+ # otherwise return nil
113
+ def tok_authentication(object, password)
114
+ return object.tok_auth(password)
115
+ end
116
+
117
+ # tokens: hash with a devise_token key or token key
118
+ # if any of the tokens is found. Provide access to the related
119
+ # object calling the method provide_access
120
+ # otherwise return nil
121
+ def validate_access(tokens = {})
122
+ toks_class = Object.const_get("#{self.name.camelize}Tok")
123
+ tok = toks_class.find_by(devise_token: tokens[:devise_token]) if tokens[:devise_token]
124
+ tok = toks_class.find_by(token: tokens[:token]) if tokens[:token] and !tok
125
+ if tok
126
+ return tok._tok_object.provide_access(tok)
127
+ end
128
+ nil
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,52 @@
1
+ module TokAccess
2
+
3
+ class TokConfig
4
+
5
+ attr_accessor :tokens_limit
6
+ @tokens_limit = nil
7
+
8
+ def initialize()
9
+ @tokens_limit = 10
10
+ end
11
+
12
+ end
13
+
14
+ @config = TokConfig.new
15
+
16
+ def config
17
+ @config
18
+ end
19
+ module_function :config
20
+
21
+ def configure(&block)
22
+ if block_given?
23
+ yield @config
24
+ end
25
+ end
26
+ module_function :configure
27
+
28
+ Object.class_eval do
29
+ def tokify
30
+ class_eval do
31
+ include TokAccess::TokAuthenticable
32
+ has_secure_password
33
+ has_many :toks, class_name: "#{self}Tok", foreign_key: "object_id", autosave: true
34
+ end
35
+ end
36
+
37
+ def define_toks(association = nil)
38
+ class_eval do
39
+ belongs_to association,
40
+ class_name: "#{self.to_s.gsub(/Tok\z/,'')}",
41
+ foreign_key: "object_id" if association
42
+ belongs_to :_tok_object,
43
+ class_name: "#{self.to_s.gsub(/Tok\z/,'')}",
44
+ foreign_key: "object_id" if association
45
+ has_secure_token
46
+ has_secure_token :devise_token
47
+ validates :token, :devise_token, presence: true, on: :update
48
+ end
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,3 @@
1
+ module TokAccess
2
+ VERSION = '1.0.0'
3
+ end
data/lib/tok_access.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'tok_access/tok_config'
2
+ require 'tok_access/tok_authenticable'
3
+
4
+ ## TokAccess
5
+ # The TokAcess module
6
+ module TokAccess
7
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tok_access
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yonga9121
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bcrypt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.1.7
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.1.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Handle authentication of your users using tokens.
56
+ email:
57
+ - jorgeggayon@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - MIT-LICENSE
63
+ - README.md
64
+ - Rakefile
65
+ - lib/generators/tok_access/USAGE
66
+ - lib/generators/tok_access/model_generator.rb
67
+ - lib/generators/tok_access/orm_helper.rb
68
+ - lib/generators/tok_access/templates/migration_existing_for.rb
69
+ - lib/generators/tok_access/templates/migration_for.rb
70
+ - lib/generators/tok_access/tok_access_generator.rb
71
+ - lib/tasks/tok_access_tasks.rake
72
+ - lib/tok_access.rb
73
+ - lib/tok_access/tok_authenticable.rb
74
+ - lib/tok_access/tok_config.rb
75
+ - lib/tok_access/version.rb
76
+ homepage: https://yonga9121.github.io/tok_access/
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.6.13
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Handle authentication of your users using tokens.
100
+ test_files: []