founders_toolkit 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8bab9cf8b0f8b1e823fc932ac004d9a6dbfbb16ad0be8323024816ad3b49ad3a
4
+ data.tar.gz: b075d2997a6c2603cdcfc0d8b94964da46bc7a35d1f07e5ed6b1579d2063477d
5
+ SHA512:
6
+ metadata.gz: 74f298a09bf4cb3918bd236c8fef80045659719f2038b677a2fc4028a5f69f3fcbe83cba2c3acf8868022fbd519effcb667fdd207dddc5e901f3a8a8094a788a
7
+ data.tar.gz: cf286d3983eef5e35ca56f500c315bf0ea13cdd4216706b0dd3aa4ef7707c471479469283fa5f8bc27ac369d7a92d3507749d16e0b2db17c30dacf8fe557bd36
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ vendor/
2
+ .rubocop-*
data/.rubocop.yml ADDED
@@ -0,0 +1,392 @@
1
+ AllCops:
2
+ Exclude:
3
+ - "vendor/**/*"
4
+ - "db/**/*"
5
+ UseCache: false
6
+ SuggestExtensions: false
7
+ Metrics/BlockLength:
8
+ IgnoredMethods: [
9
+ 'class_methods',
10
+ 'context',
11
+ 'define',
12
+ 'describe',
13
+ 'it',
14
+ 'let',
15
+ 'namespace',
16
+ 'task'
17
+ ]
18
+ Style/CollectionMethods:
19
+ Description: Preferred collection methods.
20
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
21
+ Enabled: true
22
+ PreferredMethods:
23
+ collect: map
24
+ collect!: map!
25
+ find_all: select
26
+ reduce:
27
+ inject: reduce
28
+ find:
29
+ detect: find
30
+ Style/GuardClause:
31
+ Description: Check for conditionals that can be replaced with guard clauses
32
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
33
+ Enabled: true
34
+ MinBodyLength: 1
35
+ Style/IfUnlessModifier:
36
+ Description: Favor modifier if/unless usage when you have a single-line body.
37
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
38
+ Enabled: true
39
+ Style/OptionHash:
40
+ Description: Don't use option hashes when you can use keyword arguments.
41
+ Enabled: true
42
+ Style/PercentLiteralDelimiters:
43
+ Description: Use `%`-literal delimiters consistently
44
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
45
+ Enabled: true
46
+ PreferredDelimiters:
47
+ "%": "()"
48
+ "%i": "()"
49
+ "%q": "()"
50
+ "%Q": "()"
51
+ "%r": "{}"
52
+ "%s": "()"
53
+ "%w": "()"
54
+ "%W": "()"
55
+ "%x": "()"
56
+ Style/RaiseArgs:
57
+ Description: Checks the arguments passed to raise/fail.
58
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
59
+ Enabled: true
60
+ EnforcedStyle: exploded
61
+ SupportedStyles:
62
+ - compact
63
+ - exploded
64
+ Style/SignalException:
65
+ Description: Checks for proper usage of fail and raise.
66
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
67
+ Enabled: true
68
+ EnforcedStyle: semantic
69
+ SupportedStyles:
70
+ - only_raise
71
+ - only_fail
72
+ - semantic
73
+ Style/SingleLineBlockParams:
74
+ Description: Enforces the names of some block params.
75
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
76
+ Enabled: true
77
+ Methods:
78
+ - reduce:
79
+ - a
80
+ - e
81
+ - inject:
82
+ - a
83
+ - e
84
+ Style/SingleLineMethods:
85
+ Description: Avoid single-line methods.
86
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
87
+ Enabled: true
88
+ AllowIfMethodIsEmpty: true
89
+ Style/StringLiterals:
90
+ Description: Checks if uses of quotes match the configured preference.
91
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
92
+ Enabled: true
93
+ Style/StringLiteralsInInterpolation:
94
+ Description: Checks if uses of quotes inside expressions in interpolated strings
95
+ match the configured preference.
96
+ Enabled: true
97
+ EnforcedStyle: single_quotes
98
+ SupportedStyles:
99
+ - single_quotes
100
+ - double_quotes
101
+ Style/TrailingCommaInArguments:
102
+ EnforcedStyleForMultiline: no_comma
103
+ Style/TrailingCommaInArrayLiteral:
104
+ EnforcedStyleForMultiline: no_comma
105
+ Metrics/AbcSize:
106
+ Description: A calculated magnitude based on number of assignments, branches, and
107
+ conditions.
108
+ Enabled: false
109
+ Max: 15
110
+ Metrics/ClassLength:
111
+ Description: Avoid classes longer than 100 lines of code.
112
+ Enabled: false
113
+ CountComments: false
114
+ Max: 100
115
+ Metrics/ModuleLength:
116
+ CountComments: false
117
+ Max: 100
118
+ Description: Avoid modules longer than 100 lines of code.
119
+ Enabled: false
120
+ Metrics/CyclomaticComplexity:
121
+ Description: A complexity metric that is strongly correlated to the number of test
122
+ cases needed to validate a method.
123
+ Enabled: true
124
+ Max: 6
125
+ Metrics/MethodLength:
126
+ Description: Avoid methods longer than 10 lines of code.
127
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
128
+ Enabled: false
129
+ CountComments: false
130
+ Max: 10
131
+ Metrics/ParameterLists:
132
+ Description: Avoid parameter lists longer than three or four parameters.
133
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
134
+ Enabled: false
135
+ Max: 5
136
+ CountKeywordArgs: true
137
+ Metrics/PerceivedComplexity:
138
+ Description: A complexity metric geared towards measuring complexity for a human
139
+ reader.
140
+ Enabled: false
141
+ Max: 7
142
+ Layout/LineLength:
143
+ Max: 100
144
+ # To make it possible to copy or click on URIs in the code, we allow lines
145
+ # contaning a URI to be longer than Max.
146
+ AllowURI: true
147
+ URISchemes:
148
+ - http
149
+ - https
150
+ Lint/AssignmentInCondition:
151
+ Description: Don't use assignment in conditions.
152
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
153
+ Enabled: true
154
+ AllowSafeAssignment: true
155
+ Style/InlineComment:
156
+ Description: Avoid inline comments.
157
+ Enabled: false
158
+ Style/Alias:
159
+ Description: Use alias_method instead of alias.
160
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
161
+ Enabled: true
162
+ Style/Documentation:
163
+ Description: Document classes and non-namespace modules.
164
+ Enabled: false
165
+ Style/DoubleNegation:
166
+ Description: Checks for uses of double negation (!!).
167
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
168
+ Enabled: true
169
+ Style/EachWithObject:
170
+ Description: Prefer `each_with_object` over `inject` or `reduce`.
171
+ Enabled: false
172
+ Style/EmptyLiteral:
173
+ Description: Prefer literals to Array.new/Hash.new/String.new.
174
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
175
+ Enabled: true
176
+ Style/ModuleFunction:
177
+ Description: Checks for usage of `extend self` in modules.
178
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
179
+ Enabled: true
180
+ Style/OneLineConditional:
181
+ Description: Favor the ternary operator(?:) over if/then/else/end constructs.
182
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
183
+ Enabled: true
184
+ Style/PerlBackrefs:
185
+ Description: Avoid Perl-style regex back references.
186
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
187
+ Enabled: true
188
+ Style/Send:
189
+ Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
190
+ may overlap with existing methods.
191
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
192
+ Enabled: true
193
+ Style/SpecialGlobalVars:
194
+ Description: Avoid Perl-style global variables.
195
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
196
+ Enabled: true
197
+ Style/VariableInterpolation:
198
+ Description: Don't interpolate global, instance and class variables directly in
199
+ strings.
200
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
201
+ Enabled: false
202
+ Style/WhenThen:
203
+ Description: Use when x then ... for one-line cases.
204
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
205
+ Enabled: true
206
+ Lint/EachWithObjectArgument:
207
+ Description: Check for immutable argument given to each_with_object.
208
+ Enabled: true
209
+ Lint/SuppressedException:
210
+ Description: Don't suppress exception.
211
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
212
+ Enabled: false
213
+ Lint/LiteralAsCondition:
214
+ Description: Checks of literals used in conditions.
215
+ Enabled: true
216
+ Lint/LiteralInInterpolation:
217
+ Description: Checks for literals used in interpolation.
218
+ Enabled: true
219
+ Layout/DotPosition:
220
+ Description: Checks the position of the dot in multi-line method calls.
221
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
222
+ Enabled: true
223
+ EnforcedStyle: leading
224
+ SupportedStyles:
225
+ - leading
226
+ - trailing
227
+ Layout/MultilineOperationIndentation:
228
+ EnforcedStyle: indented
229
+ SupportedStyles:
230
+ - aligned
231
+ - indented
232
+ Layout/MultilineMethodCallIndentation:
233
+ EnforcedStyle: indented
234
+ SupportedStyles:
235
+ - aligned
236
+ - indented
237
+ Layout/SpaceInsidePercentLiteralDelimiters:
238
+ Description: 'No unnecessary spaces inside delimiters of %i/%w/%x literals.'
239
+ Enabled: false
240
+ Layout/SpaceInLambdaLiteral:
241
+ Description: 'Checks for spaces in lambda literals.'
242
+ Enabled: false
243
+ Naming/FileName:
244
+ Description: Use snake_case for source file names.
245
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
246
+ Enabled: true
247
+ Exclude: []
248
+ Naming/PredicateName:
249
+ Description: Check the names of predicate methods.
250
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
251
+ Enabled: true
252
+ NamePrefix:
253
+ - is_
254
+ - has_
255
+ - have_
256
+ ForbiddenPrefixes:
257
+ - is_
258
+ Exclude:
259
+ - spec/**/*
260
+ Naming/AccessorMethodName:
261
+ Description: Check the naming of accessor methods for get_/set_.
262
+ Enabled: false
263
+ Layout/EmptyLinesAroundAttributeAccessor:
264
+ Description: "Keep blank lines around attribute accessors."
265
+ Enabled: true
266
+ AllowAliasSyntax: true
267
+ AllowedMethods:
268
+ - alias_method
269
+ - public
270
+ - protected
271
+ - private
272
+ Layout/SpaceAroundMethodCallOperator:
273
+ Description: 'Checks method call operators to not have spaces around them.'
274
+ Enabled: true
275
+ Lint/DeprecatedOpenSSLConstant:
276
+ Description: "Don't use algorithm constants for `OpenSSL::Cipher` and `OpenSSL::Digest`."
277
+ Enabled: true
278
+ Lint/MixedRegexpCaptureTypes:
279
+ Description: 'Do not mix named captures and numbered captures in a Regexp literal.'
280
+ Enabled: true
281
+ Lint/RaiseException:
282
+ Description: Checks for `raise` or `fail` statements which are raising `Exception` class.
283
+ Enabled: true
284
+ Safe: false
285
+ AllowedImplicitNamespaces:
286
+ - 'Gem'
287
+ Lint/StructNewOverride:
288
+ Description: 'Disallow overriding the `Struct` built-in methods via `Struct.new`.'
289
+ Enabled: true
290
+ Style/ExponentialNotation:
291
+ Description: 'When using exponential notation, favor a mantissa between 1 (inclusive) and 10 (exclusive).'
292
+ Enabled: true
293
+ EnforcedStyle: scientific
294
+ SupportedStyles:
295
+ - scientific
296
+ - engineering
297
+ - integral
298
+ Style/HashEachMethods:
299
+ Description: 'Use Hash#each_key and Hash#each_value.'
300
+ Enabled: true
301
+ Safe: false
302
+ Style/HashTransformKeys:
303
+ Description: 'Prefer `transform_keys` over `each_with_object` and `map`.'
304
+ Enabled: true
305
+ Safe: false
306
+ Style/HashTransformValues:
307
+ Description: 'Prefer `transform_values` over `each_with_object` and `map`.'
308
+ Enabled: true
309
+ Safe: false
310
+ Style/RedundantFetchBlock:
311
+ Description: >-
312
+ Use `fetch(key, value)` instead of `fetch(key) { value }`
313
+ when value has Numeric, Rational, Complex, Symbol or String type, `false`, `true`, `nil` or is a constant.
314
+ Enabled: true
315
+ Safe: false
316
+ SafeForConstants: false
317
+ Style/RedundantRegexpCharacterClass:
318
+ Description: 'Checks for unnecessary single-element Regexp character classes.'
319
+ Enabled: true
320
+ Style/RedundantRegexpEscape:
321
+ Description: 'Checks for redundant escapes in Regexps.'
322
+ Enabled: true
323
+ Style/SlicingWithRange:
324
+ Description: 'Checks array slicing is done with endless ranges when suitable.'
325
+ Enabled: true
326
+ Safe: false
327
+ Style/AccessorGrouping:
328
+ Enabled: true
329
+ Style/BisectedAttrAccessor:
330
+ Enabled: true
331
+ Style/RedundantAssignment:
332
+ Enabled: true
333
+ Style/FrozenStringLiteralComment:
334
+ Enabled: true
335
+ Style/ClassAndModuleChildren:
336
+ EnforcedStyle: compact
337
+ Lint/DuplicateElsifCondition:
338
+ Enabled: true
339
+ Style/ArrayCoercion:
340
+ Enabled: true
341
+ Style/CaseLikeIf:
342
+ Enabled: true
343
+ Style/HashAsLastArrayItem:
344
+ Enabled: true
345
+ Style/HashLikeCase:
346
+ Enabled: true
347
+ Style/RedundantFileExtensionInRequire:
348
+ Enabled: true
349
+ Lint/DuplicateRegexpCharacterClassElement:
350
+ Enabled: true
351
+ Lint/EmptyBlock:
352
+ Enabled: true
353
+ Lint/ToEnumArguments:
354
+ Enabled: true
355
+ Lint/UnmodifiedReduceAccumulator:
356
+ Enabled: true
357
+ Style/ArgumentsForwarding:
358
+ Enabled: true
359
+ Style/DocumentDynamicEvalDefinition:
360
+ Enabled: true
361
+ Style/SwapValues:
362
+ Enabled: true
363
+ Layout/SpaceBeforeBrackets:
364
+ Enabled: true
365
+ Lint/AmbiguousAssignment:
366
+ Enabled: true
367
+ Lint/DuplicateBranch:
368
+ Enabled: true
369
+ Lint/EmptyClass:
370
+ Enabled: true
371
+ Lint/NoReturnInBeginEndBlocks:
372
+ Enabled: true
373
+ Lint/UnexpectedBlockArity:
374
+ Enabled: true
375
+ Style/CollectionCompact:
376
+ Enabled: true
377
+ Style/HashExcept:
378
+ Enabled: true
379
+ Style/NegatedIfElseCondition:
380
+ Enabled: true
381
+ Style/NilLambda:
382
+ Enabled: true
383
+ Style/RedundantArgument:
384
+ Enabled: true
385
+ Lint/DeprecatedConstants:
386
+ Enabled: true
387
+ Lint/LambdaWithoutLiteralBlock:
388
+ Enabled: true
389
+ Lint/RedundantDirGlobSort:
390
+ Enabled: true
391
+ Style/EndlessMethod:
392
+ Enabled: true
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in founders_toolkit.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 13.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'rubocop', '~> 1.7'
data/Gemfile.lock ADDED
@@ -0,0 +1,72 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ founders_toolkit (0.1.0)
5
+ activemodel (~> 6.1)
6
+ activesupport (~> 6.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (6.1.3)
12
+ activesupport (= 6.1.3)
13
+ activesupport (6.1.3)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 1.6, < 2)
16
+ minitest (>= 5.1)
17
+ tzinfo (~> 2.0)
18
+ zeitwerk (~> 2.3)
19
+ ast (2.4.2)
20
+ concurrent-ruby (1.1.8)
21
+ diff-lcs (1.4.4)
22
+ i18n (1.8.9)
23
+ concurrent-ruby (~> 1.0)
24
+ minitest (5.14.4)
25
+ parallel (1.20.1)
26
+ parser (3.0.0.0)
27
+ ast (~> 2.4.1)
28
+ rainbow (3.0.0)
29
+ rake (13.0.3)
30
+ regexp_parser (2.1.1)
31
+ rexml (3.2.4)
32
+ rspec (3.10.0)
33
+ rspec-core (~> 3.10.0)
34
+ rspec-expectations (~> 3.10.0)
35
+ rspec-mocks (~> 3.10.0)
36
+ rspec-core (3.10.1)
37
+ rspec-support (~> 3.10.0)
38
+ rspec-expectations (3.10.1)
39
+ diff-lcs (>= 1.2.0, < 2.0)
40
+ rspec-support (~> 3.10.0)
41
+ rspec-mocks (3.10.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.10.0)
44
+ rspec-support (3.10.2)
45
+ rubocop (1.11.0)
46
+ parallel (~> 1.10)
47
+ parser (>= 3.0.0.0)
48
+ rainbow (>= 2.2.2, < 4.0)
49
+ regexp_parser (>= 1.8, < 3.0)
50
+ rexml
51
+ rubocop-ast (>= 1.2.0, < 2.0)
52
+ ruby-progressbar (~> 1.7)
53
+ unicode-display_width (>= 1.4.0, < 3.0)
54
+ rubocop-ast (1.4.1)
55
+ parser (>= 2.7.1.5)
56
+ ruby-progressbar (1.11.0)
57
+ tzinfo (2.0.4)
58
+ concurrent-ruby (~> 1.0)
59
+ unicode-display_width (2.0.0)
60
+ zeitwerk (2.4.2)
61
+
62
+ PLATFORMS
63
+ x86_64-darwin-19
64
+
65
+ DEPENDENCIES
66
+ founders_toolkit!
67
+ rake (~> 13.0)
68
+ rspec (~> 3.0)
69
+ rubocop (~> 1.7)
70
+
71
+ BUNDLED WITH
72
+ 2.2.15
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Trae Robrock
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # FoundersToolkit
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/founders_toolkit/auth`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'founders-toolkit-auth'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install founders-toolkit-auth
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ 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.
30
+
31
+ 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/founders-toolkit-auth.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "founders_toolkit/auth"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ 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
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/founders_toolkit/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'founders_toolkit'
7
+ spec.version = FoundersToolkit::VERSION
8
+ spec.authors = ['Trae Robrock', 'Andrew Katz']
9
+ spec.email = ['trobrock@gmail.com', 'andrew.katz@hey.com']
10
+
11
+ spec.summary = 'Founders Toolkit for Rails'
12
+ spec.description = 'Founders Toolkit for Rails'
13
+ spec.homepage = 'https://github.com/trobrock/founders-toolkit'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/trobrock/founders-toolkit.git'
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
24
+ end
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'activemodel', '~> 6.1'
30
+ spec.add_dependency 'activesupport', '~> 6.1'
31
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'founders_toolkit/version'
4
+ require_relative 'founders_toolkit/engine'
5
+
6
+ module FoundersToolkit
7
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Confirmable
4
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Confirmable::Model
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include FoundersToolkit::Auth::Emailable::Model
8
+
9
+ has_secure_token :confirmation_token
10
+ after_create :send_confirmation_email
11
+ end
12
+
13
+ def self.confirm!(token)
14
+ find_by(token: token)&.confirm!
15
+ end
16
+
17
+ def confirm!
18
+ update(confirmed: true, confirmation_token: nil)
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Emailable
4
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Emailable::Model
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ begin
8
+ require 'email_validator'
9
+ rescue LoadError
10
+ puts 'FoundersToolkit::Auth::Emailable requires the `email_validator` gem!'
11
+ raise
12
+ end
13
+ validates :email,
14
+ presence: true,
15
+ email: { mode: :strict, require_fqdn: true },
16
+ uniqueness: { case_sensitive: false }
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Recoverable
4
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Recoverable::Model
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include FoundersToolkit::Auth::Confirmable::Model
8
+
9
+ before_save :clear_reset_password_token, if: :password_digest_changed?
10
+ end
11
+
12
+ def generate_reset_password_token!
13
+ update(reset_password_token: self.class.generate_unique_secure_token)
14
+ end
15
+
16
+ def clear_reset_password_token
17
+ self.reset_password_token = nil
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Securable
4
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Securable::Controller
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :redirect_if_set
8
+ before_action :set_current_user
9
+ before_action :authenticate
10
+ end
11
+
12
+ def sign_in(user)
13
+ session[:user_id] = user.id
14
+ end
15
+
16
+ private
17
+
18
+ def redirect_if_set
19
+ return unless session[:redirect_to]
20
+
21
+ path = session.delete(:redirect_to)
22
+ redirect_to path
23
+ end
24
+
25
+ def set_current_user
26
+ Current.user = User.find_by(id: session[:user_id]) if session[:user_id]
27
+ end
28
+
29
+ def authenticate
30
+ return if Current.user.present?
31
+
32
+ session[:redirect_to] = request.env['PATH_INFO']
33
+ redirect_to new_session_path
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Securable::CurrentAttributes
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ attribute :user
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Securable::Model
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include FoundersToolkit::Auth::Emailable::Model
8
+ extend FoundersToolkit::Auth::Securable::Validations::ProtectedValidator::HelperMethods
9
+
10
+ validates_protected_attributes :email
11
+ validates_protected_attributes :password, secure: true
12
+
13
+ has_secure_password
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FoundersToolkit::Auth::Securable::SessionsController < ApplicationController
4
+ include FoundersToolkit::Auth::Securable::Controller
5
+
6
+ skip_before_action :redirect_if_set
7
+ before_action :authenticate, except: %i( new create )
8
+
9
+ def new; end
10
+
11
+ def create
12
+ @user = User.find_by(email: params[:email])
13
+
14
+ if @user&.authenticate(params[:password])
15
+ session[:user_id] = @user.id
16
+ redirect_to after_login_path
17
+ else
18
+ redirect_to new_session_path, alert: 'We could not sign you in with those credentials.'
19
+ end
20
+ end
21
+
22
+ def destroy
23
+ reset_session
24
+ redirect_to after_logout_path
25
+ end
26
+
27
+ private
28
+
29
+ def after_login_path
30
+ root_path
31
+ end
32
+
33
+ def after_logout_path
34
+ root_path
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Auth::Securable::Validations
4
+ class ProtectedValidator < ActiveModel::EachValidator
5
+ def initialize(options)
6
+ super({ case_sensitive: true }.merge!(options))
7
+ setup! options[:class]
8
+ end
9
+
10
+ def validate_each(record, attribute, _value)
11
+ return unless attribute_changed?(record, attribute)
12
+ return if authenticate?(record)
13
+
14
+ human_attribute_name = record.class.human_attribute_name(attribute)
15
+ record.errors.add(
16
+ :current_password,
17
+ "Your current password is required to update your #{human_attribute_name}"
18
+ )
19
+ end
20
+
21
+ private
22
+
23
+ def setup!(klass)
24
+ klass.attr_accessor :current_password
25
+ end
26
+
27
+ def attribute_changed?(record, attribute)
28
+ attribute = "#{attribute}_digest" if options[:secure]
29
+ record.public_send("#{attribute}_changed?")
30
+ end
31
+
32
+ def authenticate?(record)
33
+ record.try(:reset_password_token?) || record.authenticate(record.current_password)
34
+ end
35
+
36
+ module HelperMethods
37
+ def validates_protected_attributes(*attr_names)
38
+ validates_with ProtectedValidator, _merge_attributes(attr_names)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FoundersToolkit::Engine < ::Rails::Engine
4
+ config.autoload_paths << File.expand_path('..', __dir__)
5
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Jobs
4
+ module LockedJob
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include FoundersToolkit::Util::Lockable
9
+ attr_accessor :current_lock
10
+ end
11
+
12
+ class_methods do
13
+ def lock(ttl:, enqueue_ttl: 3_600_000)
14
+ before_enqueue do |_job|
15
+ enqueue_lock = locker.lock(enqueue_lock_key, enqueue_ttl)
16
+ throw :abort unless enqueue_lock
17
+
18
+ persist_lock_info(enqueue_lock)
19
+ end
20
+
21
+ before_perform do |_job|
22
+ enqueue_lock = get_lock_info
23
+ if enqueue_lock
24
+ locker.unlock(enqueue_lock)
25
+ delete_lock_info
26
+ end
27
+ end
28
+
29
+ around_perform do |job, block|
30
+ self.current_lock = locker.lock(lock_key, ttl)
31
+
32
+ if current_lock
33
+ begin
34
+ block.call
35
+ ensure
36
+ locker.unlock(current_lock)
37
+ end
38
+ else
39
+ self.class.set(wait: ttl / 1000 / 2).perform_later(*job.arguments)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ def extend_lock(ttl)
46
+ self.current_lock = locker.lock(lock_key,
47
+ ttl,
48
+ extend: current_lock,
49
+ extend_only_if_locked: true) || current_lock
50
+ end
51
+
52
+ private
53
+
54
+ def persist_lock_info(lock_info)
55
+ Resque.redis.set(lock_info_key, lock_info.to_json)
56
+ end
57
+
58
+ def get_lock_info
59
+ info = Resque.redis.get(lock_info_key)
60
+ return unless info
61
+
62
+ JSON.parse(info).symbolize_keys
63
+ end
64
+
65
+ def delete_lock_info
66
+ Resque.redis.del(lock_info_key)
67
+ end
68
+
69
+ def lock_info_key
70
+ "locked_job:#{job_id}"
71
+ end
72
+
73
+ def enqueue_lock_key
74
+ [self.class.name, 'enqueue'].concat(serialize['arguments']).join('-')
75
+ end
76
+
77
+ def lock_key
78
+ [self.class.name].concat(serialize['arguments']).join('-')
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Monitoring
4
+ module Statsdable
5
+ extend ActiveSupport::Concern
6
+
7
+ def statsd
8
+ Rails.application.config.statsd
9
+ end
10
+
11
+ class_methods do
12
+ def time(method_name)
13
+ wrapper = Module.new do
14
+ define_method(method_name) do |*args|
15
+ statsd.time [self.class.name, method_name].join('.') do
16
+ super(*args)
17
+ end
18
+ end
19
+ end
20
+ prepend wrapper
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Util
4
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit::Util
4
+ module Cacheable
5
+ extend ActiveSupport::Concern
6
+
7
+ class_methods do
8
+ def cached(method_name)
9
+ define_method("cached_#{method_name}") do |*args|
10
+ Rails.cache.fetch([method_name, *args]) do
11
+ __send__("unlocked_#{method_name}".to_sym, *args)
12
+ end
13
+ end
14
+
15
+ alias_method "cached_#{method_name}".to_sym, method_name.to_sym
16
+ alias_method method_name.to_sym, "cached_#{method_name}".to_sym
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'redlock'
5
+ rescue LoadError
6
+ puts 'FoundersToolkit::Util::Lockable requires `redlock` to be installed!'
7
+ raise
8
+ end
9
+
10
+ module FoundersToolkit::Util
11
+ module Lockable
12
+ extend ActiveSupport::Concern
13
+
14
+ def locker
15
+ @locker ||= Redlock::Client.new([Redis.new])
16
+ end
17
+
18
+ def with_lock(name, ttl, &block)
19
+ locker.lock!(name, ttl, &block)
20
+ end
21
+
22
+ class_methods do
23
+ def locked(method_name, ttl, name_proc)
24
+ define_method("locked_#{method_name}") do |*args|
25
+ lock_name = instance_exec(&name_proc)
26
+ lock = locker.lock(lock_name, ttl)
27
+ return unless lock
28
+
29
+ begin
30
+ __send__("unlocked_#{method_name}".to_sym, *args)
31
+ ensure
32
+ locker.unlock(lock)
33
+ end
34
+ end
35
+
36
+ alias_method "unlocked_#{method_name}".to_sym, method_name.to_sym
37
+ alias_method method_name.to_sym, "locked_#{method_name}".to_sym
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'ratelimit'
5
+ rescue LoadError
6
+ puts 'FoundersToolkit::Util::RateLimitable requires the `ratelimit` gem!'
7
+ raise
8
+ end
9
+
10
+ begin
11
+ require 'retryable'
12
+ rescue LoadError
13
+ puts 'FoundersToolkit::Util::RateLimitable requires the `retryable` gem!'
14
+ raise
15
+ end
16
+
17
+ require_relative '../monitoring/statsdable'
18
+
19
+ module FoundersToolkit::Util
20
+ module RateLimitable
21
+ extend ActiveSupport::Concern
22
+
23
+ included do
24
+ include FoundersToolkit::Monitoring::Statsdable
25
+ end
26
+
27
+ class_methods do
28
+ def rate_limiter(name, key:, threshold:, interval:, retry_from: [])
29
+ limiter_name = "#{name}_limiter"
30
+ define_method(limiter_name) do |&block|
31
+ limiter = instance_variable_get("@#{limiter_name}".to_sym)
32
+ limiter ||= instance_variable_set("@#{limiter_name}".to_sym, Ratelimit.new(name))
33
+
34
+ limiter.exec_within_threshold(__send__(key), threshold: threshold, interval: interval) do
35
+ result = statsd.time(['retryable', limiter_name].join('.')) do
36
+ Retryable.retryable(tries: 3, on: retry_from) { block.call }
37
+ end
38
+ limiter.add __send__(key)
39
+ result
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FoundersToolkit
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: founders_toolkit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Trae Robrock
8
+ - Andrew Katz
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2021-03-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemodel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '6.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '6.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '6.1'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '6.1'
42
+ description: Founders Toolkit for Rails
43
+ email:
44
+ - trobrock@gmail.com
45
+ - andrew.katz@hey.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - ".rubocop.yml"
52
+ - Gemfile
53
+ - Gemfile.lock
54
+ - LICENSE.txt
55
+ - README.md
56
+ - Rakefile
57
+ - bin/console
58
+ - bin/setup
59
+ - founders_toolkit.gemspec
60
+ - lib/founders_toolkit.rb
61
+ - lib/founders_toolkit/auth.rb
62
+ - lib/founders_toolkit/auth/confirmable.rb
63
+ - lib/founders_toolkit/auth/confirmable/model.rb
64
+ - lib/founders_toolkit/auth/emailable.rb
65
+ - lib/founders_toolkit/auth/emailable/model.rb
66
+ - lib/founders_toolkit/auth/recoverable.rb
67
+ - lib/founders_toolkit/auth/recoverable/model.rb
68
+ - lib/founders_toolkit/auth/securable.rb
69
+ - lib/founders_toolkit/auth/securable/controller.rb
70
+ - lib/founders_toolkit/auth/securable/current_attributes.rb
71
+ - lib/founders_toolkit/auth/securable/model.rb
72
+ - lib/founders_toolkit/auth/securable/sessions_controller.rb
73
+ - lib/founders_toolkit/auth/securable/validations/protected_validator.rb
74
+ - lib/founders_toolkit/engine.rb
75
+ - lib/founders_toolkit/jobs/locked_job.rb
76
+ - lib/founders_toolkit/monitoring/statsdable.rb
77
+ - lib/founders_toolkit/util.rb
78
+ - lib/founders_toolkit/util/cacheable.rb
79
+ - lib/founders_toolkit/util/lockable.rb
80
+ - lib/founders_toolkit/util/rate_limitable.rb
81
+ - lib/founders_toolkit/version.rb
82
+ homepage: https://github.com/trobrock/founders-toolkit
83
+ licenses:
84
+ - MIT
85
+ metadata:
86
+ homepage_uri: https://github.com/trobrock/founders-toolkit
87
+ source_code_uri: https://github.com/trobrock/founders-toolkit.git
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 2.4.0
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.2.4
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Founders Toolkit for Rails
107
+ test_files: []