pkce_oauth 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97372c190ea0a108c58d6483b1671335b1825fc6ca1f33d09d9b979599c98498
4
- data.tar.gz: 106a46dedb288e854afb0eb3a1a62cb0f4875c5d7799bb4f309e8b4139efa522
3
+ metadata.gz: 2b318658ee574454f7b5c521cdf74f16f2d459e9eb24d79d20990a854b3cdabe
4
+ data.tar.gz: 16d6e810e9bd9e4b9e18bfe5be08447f1d7f4368bb6b30f0fb3f2ed9aa67ee6c
5
5
  SHA512:
6
- metadata.gz: 1ecc650d21e9a5fc2cdcc21725c198e61cc56da30a9e02398b859331430059484414bac55d84e35a5f6db272041ebaef392692c18b5a84ca4899fbb3ad7ee2f2
7
- data.tar.gz: dafbd6198bf590d0067f58ba5268b4a12bf0d336b1b35203087ec03e7cf32bf0801e779ac9104ba0bf83e7811b53af4a3ada33e887d7b51bffeb4e2557eff087
6
+ metadata.gz: 7de6bf552d019b112584551c9bdf4294c86d83d1da9a8d41b8db1a6abf498edb6d28595fa89ffe552a0af142dc90d047981cfabb33ffb3c16b7a1fb92cd3b0da
7
+ data.tar.gz: ffb20006db7b4177feff3955978df56593af763cf99318c83f5aa4e12685f5540bce93bb4c4ab5598e27de498a300f1abd50f0b962151e5647dadd1e3d78f573
data/.rubocop.yml CHANGED
@@ -1,8 +1,70 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
5
+
1
6
  AllCops:
7
+ Exclude:
8
+ - 'bin/*'
9
+ - 'tmp/**/*'
10
+ NewCops: enable
2
11
  TargetRubyVersion: 3.0
3
12
 
4
13
  Style/StringLiterals:
5
- EnforcedStyle: double_quotes
14
+ Enabled: true
15
+ EnforcedStyle: single_quotes
6
16
 
7
17
  Style/StringLiteralsInInterpolation:
18
+ Enabled: true
8
19
  EnforcedStyle: double_quotes
20
+
21
+ Style/Documentation:
22
+ Enabled: false
23
+
24
+ Style/BlockDelimiters:
25
+ Enabled: false
26
+
27
+ Style/ModuleFunction:
28
+ Enabled: false
29
+
30
+ Style/ClassAndModuleChildren:
31
+ Enabled: false
32
+
33
+ Style/OptionalBooleanParameter:
34
+ Enabled: false
35
+
36
+ Layout/LineLength:
37
+ Max: 120
38
+
39
+ # No space makes the method definition shorter and differentiates
40
+ # from a regular assignment.
41
+ Layout/SpaceAroundEqualsInParameterDefault:
42
+ EnforcedStyle: no_space
43
+
44
+ RSpec/ExampleLength:
45
+ Max: 20
46
+
47
+ RSpec/NestedGroups:
48
+ Max: 6
49
+
50
+ RSpec/ContextWording:
51
+ Prefixes:
52
+ - when
53
+ - with
54
+ - without
55
+ - and
56
+ - if
57
+ - in
58
+ - for
59
+
60
+ RSpec/MultipleMemoizedHelpers:
61
+ Enabled: false
62
+
63
+ Gemspec/RequireMFA:
64
+ Enabled: false
65
+
66
+ Gemspec/DevelopmentDependencies:
67
+ EnforcedStyle: gemspec
68
+
69
+ Metrics/MethodLength:
70
+ Max: 11
data/CHANGELOG.md CHANGED
@@ -1,4 +1,10 @@
1
- ## [Unreleased]
1
+ ## [0.2.0] - 2024-12-16
2
+ ### Added
3
+ - generating random key with charset
4
+ - url escaping for code challenge
5
+
6
+ ### Modified
7
+ - readme
2
8
 
3
9
  ## [0.1.0] - 2024-12-16
4
10
 
data/Cargo.lock CHANGED
@@ -2,6 +2,21 @@
2
2
  # It is not intended for manual editing.
3
3
  version = 4
4
4
 
5
+ [[package]]
6
+ name = "addr2line"
7
+ version = "0.24.2"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
10
+ dependencies = [
11
+ "gimli",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "adler2"
16
+ version = "2.0.0"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
19
+
5
20
  [[package]]
6
21
  name = "aho-corasick"
7
22
  version = "1.1.3"
@@ -11,6 +26,47 @@ dependencies = [
11
26
  "memchr",
12
27
  ]
13
28
 
29
+ [[package]]
30
+ name = "async-trait"
31
+ version = "0.1.83"
32
+ source = "registry+https://github.com/rust-lang/crates.io-index"
33
+ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
34
+ dependencies = [
35
+ "proc-macro2",
36
+ "quote",
37
+ "syn",
38
+ ]
39
+
40
+ [[package]]
41
+ name = "backtrace"
42
+ version = "0.3.74"
43
+ source = "registry+https://github.com/rust-lang/crates.io-index"
44
+ checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
45
+ dependencies = [
46
+ "addr2line",
47
+ "cfg-if",
48
+ "libc",
49
+ "miniz_oxide",
50
+ "object",
51
+ "rustc-demangle",
52
+ "windows-targets",
53
+ ]
54
+
55
+ [[package]]
56
+ name = "base64"
57
+ version = "0.22.1"
58
+ source = "registry+https://github.com/rust-lang/crates.io-index"
59
+ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
60
+
61
+ [[package]]
62
+ name = "base64-url"
63
+ version = "3.0.0"
64
+ source = "registry+https://github.com/rust-lang/crates.io-index"
65
+ checksum = "38e2b6c78c06f7288d5e3c3d683bde35a79531127c83b087e5d0d77c974b4b28"
66
+ dependencies = [
67
+ "base64",
68
+ ]
69
+
14
70
  [[package]]
15
71
  name = "bindgen"
16
72
  version = "0.69.5"
@@ -37,6 +93,27 @@ version = "2.6.0"
37
93
  source = "registry+https://github.com/rust-lang/crates.io-index"
38
94
  checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
39
95
 
96
+ [[package]]
97
+ name = "block-buffer"
98
+ version = "0.10.4"
99
+ source = "registry+https://github.com/rust-lang/crates.io-index"
100
+ checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
101
+ dependencies = [
102
+ "generic-array",
103
+ ]
104
+
105
+ [[package]]
106
+ name = "byteorder"
107
+ version = "1.5.0"
108
+ source = "registry+https://github.com/rust-lang/crates.io-index"
109
+ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
110
+
111
+ [[package]]
112
+ name = "bytes"
113
+ version = "1.9.0"
114
+ source = "registry+https://github.com/rust-lang/crates.io-index"
115
+ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
116
+
40
117
  [[package]]
41
118
  name = "cexpr"
42
119
  version = "0.6.0"
@@ -63,18 +140,80 @@ dependencies = [
63
140
  "libloading",
64
141
  ]
65
142
 
143
+ [[package]]
144
+ name = "cpufeatures"
145
+ version = "0.2.16"
146
+ source = "registry+https://github.com/rust-lang/crates.io-index"
147
+ checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
148
+ dependencies = [
149
+ "libc",
150
+ ]
151
+
152
+ [[package]]
153
+ name = "crypto-common"
154
+ version = "0.1.6"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
157
+ dependencies = [
158
+ "generic-array",
159
+ "typenum",
160
+ ]
161
+
162
+ [[package]]
163
+ name = "digest"
164
+ version = "0.10.7"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
167
+ dependencies = [
168
+ "block-buffer",
169
+ "crypto-common",
170
+ ]
171
+
66
172
  [[package]]
67
173
  name = "either"
68
174
  version = "1.13.0"
69
175
  source = "registry+https://github.com/rust-lang/crates.io-index"
70
176
  checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
71
177
 
178
+ [[package]]
179
+ name = "generic-array"
180
+ version = "0.14.7"
181
+ source = "registry+https://github.com/rust-lang/crates.io-index"
182
+ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
183
+ dependencies = [
184
+ "typenum",
185
+ "version_check",
186
+ ]
187
+
188
+ [[package]]
189
+ name = "getrandom"
190
+ version = "0.2.15"
191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
192
+ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
193
+ dependencies = [
194
+ "cfg-if",
195
+ "libc",
196
+ "wasi",
197
+ ]
198
+
199
+ [[package]]
200
+ name = "gimli"
201
+ version = "0.31.1"
202
+ source = "registry+https://github.com/rust-lang/crates.io-index"
203
+ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
204
+
72
205
  [[package]]
73
206
  name = "glob"
74
207
  version = "0.3.1"
75
208
  source = "registry+https://github.com/rust-lang/crates.io-index"
76
209
  checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
77
210
 
211
+ [[package]]
212
+ name = "hex"
213
+ version = "0.4.3"
214
+ source = "registry+https://github.com/rust-lang/crates.io-index"
215
+ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
216
+
78
217
  [[package]]
79
218
  name = "itertools"
80
219
  version = "0.12.1"
@@ -147,6 +286,15 @@ version = "0.2.1"
147
286
  source = "registry+https://github.com/rust-lang/crates.io-index"
148
287
  checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
149
288
 
289
+ [[package]]
290
+ name = "miniz_oxide"
291
+ version = "0.8.0"
292
+ source = "registry+https://github.com/rust-lang/crates.io-index"
293
+ checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
294
+ dependencies = [
295
+ "adler2",
296
+ ]
297
+
150
298
  [[package]]
151
299
  name = "nom"
152
300
  version = "7.1.3"
@@ -157,11 +305,38 @@ dependencies = [
157
305
  "minimal-lexical",
158
306
  ]
159
307
 
308
+ [[package]]
309
+ name = "object"
310
+ version = "0.36.5"
311
+ source = "registry+https://github.com/rust-lang/crates.io-index"
312
+ checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
313
+ dependencies = [
314
+ "memchr",
315
+ ]
316
+
317
+ [[package]]
318
+ name = "pin-project-lite"
319
+ version = "0.2.15"
320
+ source = "registry+https://github.com/rust-lang/crates.io-index"
321
+ checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
322
+
160
323
  [[package]]
161
324
  name = "pkce_oauth"
162
325
  version = "0.1.0"
163
326
  dependencies = [
327
+ "base64-url",
164
328
  "magnus",
329
+ "rand",
330
+ "sha256",
331
+ ]
332
+
333
+ [[package]]
334
+ name = "ppv-lite86"
335
+ version = "0.2.20"
336
+ source = "registry+https://github.com/rust-lang/crates.io-index"
337
+ checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
338
+ dependencies = [
339
+ "zerocopy",
165
340
  ]
166
341
 
167
342
  [[package]]
@@ -182,6 +357,36 @@ dependencies = [
182
357
  "proc-macro2",
183
358
  ]
184
359
 
360
+ [[package]]
361
+ name = "rand"
362
+ version = "0.8.5"
363
+ source = "registry+https://github.com/rust-lang/crates.io-index"
364
+ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
365
+ dependencies = [
366
+ "libc",
367
+ "rand_chacha",
368
+ "rand_core",
369
+ ]
370
+
371
+ [[package]]
372
+ name = "rand_chacha"
373
+ version = "0.3.1"
374
+ source = "registry+https://github.com/rust-lang/crates.io-index"
375
+ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
376
+ dependencies = [
377
+ "ppv-lite86",
378
+ "rand_core",
379
+ ]
380
+
381
+ [[package]]
382
+ name = "rand_core"
383
+ version = "0.6.4"
384
+ source = "registry+https://github.com/rust-lang/crates.io-index"
385
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
386
+ dependencies = [
387
+ "getrandom",
388
+ ]
389
+
185
390
  [[package]]
186
391
  name = "rb-sys"
187
392
  version = "0.9.103"
@@ -241,6 +446,12 @@ version = "0.8.5"
241
446
  source = "registry+https://github.com/rust-lang/crates.io-index"
242
447
  checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
243
448
 
449
+ [[package]]
450
+ name = "rustc-demangle"
451
+ version = "0.1.24"
452
+ source = "registry+https://github.com/rust-lang/crates.io-index"
453
+ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
454
+
244
455
  [[package]]
245
456
  name = "rustc-hash"
246
457
  version = "1.1.0"
@@ -253,6 +464,30 @@ version = "0.3.5"
253
464
  source = "registry+https://github.com/rust-lang/crates.io-index"
254
465
  checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4"
255
466
 
467
+ [[package]]
468
+ name = "sha2"
469
+ version = "0.10.8"
470
+ source = "registry+https://github.com/rust-lang/crates.io-index"
471
+ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
472
+ dependencies = [
473
+ "cfg-if",
474
+ "cpufeatures",
475
+ "digest",
476
+ ]
477
+
478
+ [[package]]
479
+ name = "sha256"
480
+ version = "1.5.0"
481
+ source = "registry+https://github.com/rust-lang/crates.io-index"
482
+ checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0"
483
+ dependencies = [
484
+ "async-trait",
485
+ "bytes",
486
+ "hex",
487
+ "sha2",
488
+ "tokio",
489
+ ]
490
+
256
491
  [[package]]
257
492
  name = "shell-words"
258
493
  version = "1.1.0"
@@ -276,12 +511,41 @@ dependencies = [
276
511
  "unicode-ident",
277
512
  ]
278
513
 
514
+ [[package]]
515
+ name = "tokio"
516
+ version = "1.42.0"
517
+ source = "registry+https://github.com/rust-lang/crates.io-index"
518
+ checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
519
+ dependencies = [
520
+ "backtrace",
521
+ "bytes",
522
+ "pin-project-lite",
523
+ ]
524
+
525
+ [[package]]
526
+ name = "typenum"
527
+ version = "1.17.0"
528
+ source = "registry+https://github.com/rust-lang/crates.io-index"
529
+ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
530
+
279
531
  [[package]]
280
532
  name = "unicode-ident"
281
533
  version = "1.0.14"
282
534
  source = "registry+https://github.com/rust-lang/crates.io-index"
283
535
  checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
284
536
 
537
+ [[package]]
538
+ name = "version_check"
539
+ version = "0.9.5"
540
+ source = "registry+https://github.com/rust-lang/crates.io-index"
541
+ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
542
+
543
+ [[package]]
544
+ name = "wasi"
545
+ version = "0.11.0+wasi-snapshot-preview1"
546
+ source = "registry+https://github.com/rust-lang/crates.io-index"
547
+ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
548
+
285
549
  [[package]]
286
550
  name = "windows-targets"
287
551
  version = "0.52.6"
@@ -345,3 +609,24 @@ name = "windows_x86_64_msvc"
345
609
  version = "0.52.6"
346
610
  source = "registry+https://github.com/rust-lang/crates.io-index"
347
611
  checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
612
+
613
+ [[package]]
614
+ name = "zerocopy"
615
+ version = "0.7.35"
616
+ source = "registry+https://github.com/rust-lang/crates.io-index"
617
+ checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
618
+ dependencies = [
619
+ "byteorder",
620
+ "zerocopy-derive",
621
+ ]
622
+
623
+ [[package]]
624
+ name = "zerocopy-derive"
625
+ version = "0.7.35"
626
+ source = "registry+https://github.com/rust-lang/crates.io-index"
627
+ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
628
+ dependencies = [
629
+ "proc-macro2",
630
+ "quote",
631
+ "syn",
632
+ ]
data/README.md CHANGED
@@ -1,30 +1,60 @@
1
1
  # PkceOauth
2
2
 
3
-
3
+ Proof Key for Code Exchange (PKCE) for ruby built with rust.
4
4
 
5
5
  ## Installation
6
6
 
7
- Install the gem and add to the application's Gemfile by executing:
7
+ Add this line to your application's Gemfile:
8
8
 
9
- ```bash
10
- bundle add pkce_oauth
9
+ ```ruby
10
+ gem 'pkce_oauth'
11
11
  ```
12
12
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
13
+ ## Usage
14
14
 
15
- ```bash
16
- gem install pkce_oauth
15
+ ```ruby
16
+ # @return [Hash] keys: code_verifier, code_challenge
17
+ # code_verifier - random key
18
+ # code_challenge - Base64 url-encoded string of the SHA256 hash of the code verifier
19
+ PkceOauth.challenge
17
20
  ```
18
21
 
19
- ## Usage
22
+ ```ruby
23
+ # @return [Hash] keys: code_verifier, code_challenge
24
+ PkceOauth.challenge(key_length: 64)
25
+ ```
26
+
27
+ ```ruby
28
+ # @return [Boolean]
29
+ PkceOauth.challenge_valid?(code_verifier: code_verifier, code_challenge: code_challenge)
30
+ ```
20
31
 
32
+ ## Usage with dry-container
21
33
 
34
+ If you use dry-container for class memoization and use `PkceOauth.challenge` with the same options, then you can add initialized objects to container
35
+
36
+ ```ruby
37
+ register('pkce_challenge') { PkceOauth::Challenge.new }
38
+ register('pkce_comparator') { PkceOauth::Comparator.new }
39
+ ```
40
+
41
+ and later call them
42
+
43
+ ```ruby
44
+ pkce_challenge.call
45
+ pkce_comparator.equal?(code_verifier: code_verifier, code_challenge: code_challenge)
46
+ ```
22
47
 
23
48
  ## Development
24
49
 
25
50
  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.
26
51
 
27
- 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).
52
+ After changing rust code in ext folder you need to compile code and run tests
53
+
54
+ ```bash
55
+ bundle exec rake compile
56
+ rspec
57
+ ```
28
58
 
29
59
  ## Contributing
30
60
 
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ RuboCop::RakeTask.new
11
11
 
12
12
  require 'rb_sys/extensiontask'
13
13
 
14
- task build: :compile
14
+ task build: :compile # rubocop: disable Rake/Desc
15
15
 
16
16
  GEMSPEC = Gem::Specification.load('pkce_oauth.gemspec')
17
17
 
@@ -10,4 +10,7 @@ publish = false
10
10
  crate-type = ["cdylib"]
11
11
 
12
12
  [dependencies]
13
+ base64-url = { version = "3.0.0" }
13
14
  magnus = { version = "0.6.2" }
15
+ rand = { version = "0.8.5" }
16
+ sha256 = { version = "1.5.0" }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "mkmf"
4
- require "rb_sys/mkmf"
3
+ require 'mkmf'
4
+ require 'rb_sys/mkmf'
5
5
 
6
- create_rust_makefile("pkce_oauth/pkce_oauth")
6
+ create_rust_makefile('pkce_oauth/pkce_oauth')
@@ -1,12 +1,35 @@
1
+ use base64_url::escape;
1
2
  use magnus::{function, prelude::*, Error, Ruby};
3
+ use rand::{thread_rng, Rng};
4
+ //use rand::distributions::Alphanumeric;
5
+ use sha256::digest;
2
6
 
3
- fn hello(subject: String) -> String {
4
- format!("Hello from Rust, {subject}!")
7
+ fn generate_limited_code_verifier(length: usize) -> String {
8
+ const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
9
+ abcdefghijklmnopqrstuvwxyz\
10
+ 0123456789-_";
11
+ let mut rng = thread_rng();
12
+ (0..length)
13
+ .map(|_| {
14
+ let index = rng.gen_range(0..CHARSET.len());
15
+ CHARSET[index] as char
16
+ })
17
+ .collect()
18
+ }
19
+
20
+ fn generate_code_verifier() -> String {
21
+ generate_limited_code_verifier(128)
22
+ }
23
+
24
+ fn generate_code_challenge(code_verifier: String) -> String {
25
+ escape(&digest(code_verifier)).to_string()
5
26
  }
6
27
 
7
28
  #[magnus::init]
8
29
  fn init(ruby: &Ruby) -> Result<(), Error> {
9
- let module = ruby.define_module("PkceOauth")?;
10
- module.define_singleton_method("hello", function!(hello, 1))?;
11
- Ok(())
30
+ let module = ruby.define_module("PkceOauth")?;
31
+ module.define_singleton_method("generate_limited_code_verifier", function!(generate_limited_code_verifier, 1))?;
32
+ module.define_singleton_method("generate_code_verifier", function!(generate_code_verifier, 0))?;
33
+ module.define_singleton_method("generate_code_challenge", function!(generate_code_challenge, 1))?;
34
+ Ok(())
12
35
  }
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PkceOauth
4
+ class Challenge
5
+ attr_reader :verifier, :challenger
6
+
7
+ def initialize(verifier: Verifier, challenger: Challenger, **options)
8
+ @verifier = verifier.new(**options.slice(:key_length))
9
+ @challenger = challenger.new
10
+ end
11
+
12
+ def call
13
+ code_verifier = verifier.call
14
+
15
+ {
16
+ code_verifier: code_verifier,
17
+ code_challenge: challenger.call(code_verifier: code_verifier)
18
+ }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PkceOauth
4
+ class Challenger
5
+ def call(code_verifier:)
6
+ PkceOauth.generate_code_challenge(code_verifier)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PkceOauth
4
+ class Comparator
5
+ attr_reader :challenger
6
+
7
+ def initialize(challenger: Challenger)
8
+ @challenger = challenger.new
9
+ end
10
+
11
+ def equal?(code_verifier:, code_challenge:)
12
+ challenger.call(code_verifier: code_verifier) == code_challenge
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PkceOauth
4
+ class Verifier
5
+ class KeyLengthError < StandardError; end
6
+
7
+ MINIMUM_KEY_LENGTH = 43
8
+ DEFAULT_KEY_LENGTH = 128
9
+
10
+ attr_reader :key_length
11
+
12
+ def initialize(key_length: DEFAULT_KEY_LENGTH)
13
+ @key_length = validate_key_length(key_length)
14
+ end
15
+
16
+ def call
17
+ PkceOauth.generate_limited_code_verifier(key_length)
18
+ end
19
+
20
+ private
21
+
22
+ def validate_key_length(value)
23
+ return value if value.is_a?(Integer) && value.between?(MINIMUM_KEY_LENGTH, DEFAULT_KEY_LENGTH)
24
+
25
+ raise KeyLengthError, 'Key length should be number between 43 and 128'
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PkceOauth
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/pkce_oauth.rb CHANGED
@@ -2,8 +2,22 @@
2
2
 
3
3
  require_relative 'pkce_oauth/version'
4
4
  require_relative 'pkce_oauth/pkce_oauth'
5
+ require_relative 'pkce_oauth/challenge'
6
+ require_relative 'pkce_oauth/comparator'
7
+ require_relative 'pkce_oauth/verifier'
8
+ require_relative 'pkce_oauth/challenger'
5
9
 
6
10
  module PkceOauth
11
+ module_function
12
+
7
13
  class Error < StandardError; end
8
14
  # Your code goes here...
15
+
16
+ def challenge(...)
17
+ PkceOauth::Challenge.new(...).call
18
+ end
19
+
20
+ def challenge_valid?(...)
21
+ PkceOauth::Comparator.new.equal?(...)
22
+ end
9
23
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pkce_oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdanov Anton
@@ -11,47 +11,47 @@ cert_chain: []
11
11
  date: 2024-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rb_sys
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.9.91
19
+ version: '13.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.9.91
26
+ version: '13.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: rake-compiler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '13.0'
33
+ version: 1.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '13.0'
40
+ version: 1.2.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake-compiler
42
+ name: rb_sys
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.2.0
47
+ version: 0.9.91
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.2.0
54
+ version: 0.9.91
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubocop
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,48 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.39'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-performance
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
69
111
  description: Code verifier and challenge generator for use in PKCE Oauth2.
70
112
  email:
71
113
  - kortirso@gmail.com
@@ -86,6 +128,10 @@ files:
86
128
  - ext/pkce_oauth/extconf.rb
87
129
  - ext/pkce_oauth/src/lib.rs
88
130
  - lib/pkce_oauth.rb
131
+ - lib/pkce_oauth/challenge.rb
132
+ - lib/pkce_oauth/challenger.rb
133
+ - lib/pkce_oauth/comparator.rb
134
+ - lib/pkce_oauth/verifier.rb
89
135
  - lib/pkce_oauth/version.rb
90
136
  - sig/pkce_oauth.rbs
91
137
  homepage: https://github.com/kortirso/pkce_oauth