pkce_oauth 0.1.0 → 0.2.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 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