]> BookStack Code Mirror - bookstack/blob - tests/Helpers/OidcJwtHelper.php
New translations notifications.php (Nepali)
[bookstack] / tests / Helpers / OidcJwtHelper.php
1 <?php
2
3 namespace Tests\Helpers;
4
5 use phpseclib3\Crypt\RSA;
6
7 /**
8  * A collection of functions to help with OIDC JWT testing.
9  * By default, unless overridden, content is provided in a correct working state.
10  */
11 class OidcJwtHelper
12 {
13     public static function defaultIssuer(): string
14     {
15         return 'https://auth.example.com';
16     }
17
18     public static function defaultClientId(): string
19     {
20         return 'xxyyzz.aaa.bbccdd.123';
21     }
22
23     public static function defaultPayload(): array
24     {
25         return [
26             'sub'                => 'abc1234def',
27             'name'               => 'Barry Scott',
28             'email'              => '[email protected]',
29             'ver'                => 1,
30             'iss'                => static::defaultIssuer(),
31             'aud'                => static::defaultClientId(),
32             'iat'                => time(),
33             'exp'                => time() + 720,
34             'jti'                => 'ID.AaaBBBbbCCCcccDDddddddEEEeeeeee',
35             'amr'                => ['pwd'],
36             'idp'                => 'fghfghgfh546456dfgdfg',
37             'preferred_username' => 'xXBazzaXx',
38             'auth_time'          => time(),
39             'at_hash'            => 'sT4jbsdSGy9w12pq3iNYDA',
40         ];
41     }
42
43     public static function idToken($payloadOverrides = [], $headerOverrides = []): string
44     {
45         $payload = array_merge(static::defaultPayload(), $payloadOverrides);
46         $header = array_merge([
47             'kid' => 'xyz456',
48             'alg' => 'RS256',
49         ], $headerOverrides);
50
51         $top = implode('.', [
52             static::base64UrlEncode(json_encode($header)),
53             static::base64UrlEncode(json_encode($payload)),
54         ]);
55
56         $privateKey = static::privateKeyInstance();
57         $signature = $privateKey->sign($top);
58
59         return $top . '.' . static::base64UrlEncode($signature);
60     }
61
62     public static function privateKeyInstance()
63     {
64         static $key;
65         if (is_null($key)) {
66             $key = RSA::loadPrivateKey(static::privatePemKey())->withPadding(RSA::SIGNATURE_PKCS1);
67         }
68
69         return $key;
70     }
71
72     public static function base64UrlEncode(string $decoded): string
73     {
74         return strtr(base64_encode($decoded), '+/', '-_');
75     }
76
77     public static function publicPemKey(): string
78     {
79         return '-----BEGIN PUBLIC KEY-----
80 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqo1OmfNKec5S2zQC4SP9
81 DrHuUR0VgCi6oqcGERz7zqO36hqk3A3R3aCgJkEjfnbnMuszRRKs45NbXoOp9pvm
82 zXL16c93Obn7G8x8A3ao6yN5qKO5S5+CETqOZfKN/g75Xlz7VsC3igOhgsXnPx6i
83 iM6sbYbk0U/XpFaT84LXKI8VTIPUo7gTeZN1pTET//i9FlzAOzX+xfWBKdOqlEzl
84 +zihMHCZUUvQu99P+o0MDR0lMUT+vPJ6SJeRfnoHexwt6bZFiNnsZIEL03bX4QNk
85 WvsLta1+jNUee+8IPVhzCO8bvM86NzLaKUJ4k6NZ5IVrmdCFpFsjCWByOrDG8wdw
86 3wIDAQAB
87 -----END PUBLIC KEY-----';
88     }
89
90     public static function privatePemKey(): string
91     {
92         return '-----BEGIN PRIVATE KEY-----
93 MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqjU6Z80p5zlLb
94 NALhI/0Ose5RHRWAKLqipwYRHPvOo7fqGqTcDdHdoKAmQSN+ducy6zNFEqzjk1te
95 g6n2m+bNcvXpz3c5ufsbzHwDdqjrI3moo7lLn4IROo5l8o3+DvleXPtWwLeKA6GC
96 xec/HqKIzqxthuTRT9ekVpPzgtcojxVMg9SjuBN5k3WlMRP/+L0WXMA7Nf7F9YEp
97 06qUTOX7OKEwcJlRS9C730/6jQwNHSUxRP688npIl5F+egd7HC3ptkWI2exkgQvT
98 dtfhA2Ra+wu1rX6M1R577wg9WHMI7xu8zzo3MtopQniTo1nkhWuZ0IWkWyMJYHI6
99 sMbzB3DfAgMBAAECggEADm7K2ghWoxwsstQh8j+DaLzx9/dIHIJV2PHdd5FGVeRQ
100 6gS7MswQmHrBUrtsb4VMZ2iz/AJqkw+jScpGldH3pCc4XELsSfxNHbseO4TNIqjr
101 4LOKOLYU4bRc3I+8KGXIAI5JzrucTJemEVUCDrte8cjbmqExt+zTyNpyxsapworF
102 v+vnSdv40d62f+cS1xvwB+ymLK/B/wZ/DemDCi8jsi7ou/M7l5xNCzjH4iMSLtOW
103 fgEhejIBG9miMJWPiVpTXE3tMdNuN3OsWc4XXm2t4VRovlZdu30Fax1xWB+Locsv
104 HlHKLOFc8g+jZh0TL2KCNjPffMcC7kHhW3afshpIsQKBgQDhyWUnkqd6FzbwIX70
105 SnaMgKoUv5W/K5T+Sv/PA2CyN8Gu8ih/OsoNZSnI0uqe3XQIvvgN/Fq3wO1ttLzf
106 z5B6ZC7REfTgcR0190gihk6f5rtcj7d6Fy/oG2CE8sDSXgPnpEaBjvJVgN5v/U2s
107 HpVaidmHTyGLCfEszoeoy8jyrQKBgQDBX8caGylmzQLc6XNntZChlt3e18Nj8MPA
108 DxWLcoqgdDoofLDQAmLl+vPKyDmhQjos5eas1jgmVVEM4ge+MysaVezvuLBsSnOh
109 ihc0i63USU6i7YDE83DrCewCthpFHi/wW1S5FoCAzpVy8y99vwcqO4kOXcmf4O6Y
110 uW6sMsjvOwKBgQDbFtqB+MtsLCSSBF61W6AHHD5tna4H75lG2623yXZF2NanFLF5
111 K6muL9DI3ujtOMQETJJUt9+rWJjLEEsJ/dYa/SV0l7D/LKOEnyuu3JZkkLaTzZzi
112 6qcA2bfhqdCzEKlHV99WjkfV8hNlpex9rLuOPB8JLh7FVONicBGxF/UojQKBgDXs
113 IlYaSuI6utilVKQP0kPtEPOKERc2VS+iRSy8hQGXR3xwwNFQSQm+f+sFCGT6VcSd
114 W0TI+6Fc2xwPj38vP465dTentbKM1E+wdSYW6SMwSfhO6ECDbfJsst5Sr2Kkt1N7
115 9FUkfDLu6GfEfnK/KR1SurZB2u51R7NYyg7EnplvAoGAT0aTtOcck0oYN30g5mdf
116 efqXPwg2wAPYeiec49EbfnteQQKAkqNfJ9K69yE2naf6bw3/5mCBsq/cXeuaBMII
117 ylysUIRBqt2J0kWm2yCpFWR7H+Ilhdx9A7ZLCqYVt8e+vjO/BOI3cQDe2VPOLPSl
118 q/1PY4iJviGKddtmfClH3v4=
119 -----END PRIVATE KEY-----';
120     }
121
122     public static function publicJwkKeyArray(): array
123     {
124         return [
125             'kty' => 'RSA',
126             'alg' => 'RS256',
127             'kid' => '066e52af-8884-4926-801d-032a276f9f2a',
128             'use' => 'sig',
129             'e'   => 'AQAB',
130             'n'   => 'qo1OmfNKec5S2zQC4SP9DrHuUR0VgCi6oqcGERz7zqO36hqk3A3R3aCgJkEjfnbnMuszRRKs45NbXoOp9pvmzXL16c93Obn7G8x8A3ao6yN5qKO5S5-CETqOZfKN_g75Xlz7VsC3igOhgsXnPx6iiM6sbYbk0U_XpFaT84LXKI8VTIPUo7gTeZN1pTET__i9FlzAOzX-xfWBKdOqlEzl-zihMHCZUUvQu99P-o0MDR0lMUT-vPJ6SJeRfnoHexwt6bZFiNnsZIEL03bX4QNkWvsLta1-jNUee-8IPVhzCO8bvM86NzLaKUJ4k6NZ5IVrmdCFpFsjCWByOrDG8wdw3w',
131         ];
132     }
133 }