@fleetbase/solid-engine 0.0.2

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.
Files changed (42) hide show
  1. package/.php-cs-fixer.php +29 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +222 -0
  4. package/addon/components/admin/solid-server-config.hbs +19 -0
  5. package/addon/components/admin/solid-server-config.js +52 -0
  6. package/addon/components/solid-brand-icon.hbs +9 -0
  7. package/addon/components/solid-brand-icon.js +13 -0
  8. package/addon/controllers/application.js +27 -0
  9. package/addon/engine.js +40 -0
  10. package/addon/routes/application.js +14 -0
  11. package/addon/routes.js +3 -0
  12. package/addon/styles/solid-engine.css +29 -0
  13. package/addon/templates/application.hbs +15 -0
  14. package/app/components/admin/solid-server-config.js +1 -0
  15. package/app/components/solid-brand-icon.js +1 -0
  16. package/app/controllers/application.js +1 -0
  17. package/app/routes/application.js +1 -0
  18. package/composer.json +96 -0
  19. package/config/environment.js +11 -0
  20. package/extension.json +8 -0
  21. package/index.js +26 -0
  22. package/package.json +134 -0
  23. package/phpstan.neon.dist +8 -0
  24. package/phpunit.xml.dist +16 -0
  25. package/server/config/solid.php +21 -0
  26. package/server/migrations/2024_04_09_064616_create_solid_identities_table.php +33 -0
  27. package/server/src/Client/OpenIDConnectClient.php +217 -0
  28. package/server/src/Client/SolidClient.php +186 -0
  29. package/server/src/Http/Controllers/OIDCController.php +32 -0
  30. package/server/src/Http/Controllers/SolidController.php +117 -0
  31. package/server/src/LegacyClient/Identity/IdentityProvider.php +174 -0
  32. package/server/src/LegacyClient/Identity/Profile.php +18 -0
  33. package/server/src/LegacyClient/OIDCClient.php +350 -0
  34. package/server/src/LegacyClient/Profile/WebID.php +26 -0
  35. package/server/src/LegacyClient/SolidClient.php +270 -0
  36. package/server/src/Models/SolidIdentity.php +131 -0
  37. package/server/src/Providers/SolidServiceProvider.php +62 -0
  38. package/server/src/Support/Utils.php +9 -0
  39. package/server/src/routes.php +47 -0
  40. package/server/tests/Feature.php +5 -0
  41. package/translations/en-us.yaml +2 -0
  42. package/tsconfig.declarations.json +10 -0
package/package.json ADDED
@@ -0,0 +1,134 @@
1
+ {
2
+ "name": "@fleetbase/solid-engine",
3
+ "version": "0.0.2",
4
+ "description": "Solid Protocol Extension to Store and Share Data with Fleetbase",
5
+ "fleetbase": {
6
+ "route": "solid-protocol"
7
+ },
8
+ "keywords": [
9
+ "fleetbase-extension",
10
+ "solid",
11
+ "solid-protocol",
12
+ "decentralized",
13
+ "decentralized-data",
14
+ "fleetbase",
15
+ "fleetbase-pod",
16
+ "rdf",
17
+ "linked-data",
18
+ "ember-addon",
19
+ "ember-engine"
20
+ ],
21
+ "repository": "https://github.com/fleetbase/solid",
22
+ "license": "MIT",
23
+ "author": "Fleetbase Pte Ltd <hello@fleetbase.io>",
24
+ "directories": {
25
+ "app": "app",
26
+ "addon": "addon",
27
+ "tests": "tests"
28
+ },
29
+ "scripts": {
30
+ "build": "ember build --environment=production",
31
+ "lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
32
+ "lint:css": "stylelint \"**/*.css\"",
33
+ "lint:css:fix": "concurrently \"npm:lint:css -- --fix\"",
34
+ "lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
35
+ "lint:hbs": "ember-template-lint .",
36
+ "lint:hbs:fix": "ember-template-lint . --fix",
37
+ "lint:js": "eslint . --cache",
38
+ "lint:js:fix": "eslint . --fix",
39
+ "start": "ember serve",
40
+ "test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"",
41
+ "test:ember": "ember test",
42
+ "test:ember-compatibility": "ember try:each",
43
+ "publish:npm": "npm config set registry https://registry.npmjs.org/ && npm publish",
44
+ "publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
45
+ },
46
+ "dependencies": {
47
+ "@babel/core": "^7.23.2",
48
+ "@fleetbase/ember-core": "^0.2.8",
49
+ "@fleetbase/ember-ui": "^0.2.12",
50
+ "@fleetbase/fleetops-data": "^0.1.14",
51
+ "@fortawesome/ember-fontawesome": "^0.4.1",
52
+ "@fortawesome/fontawesome-svg-core": "^6.4.0",
53
+ "@fortawesome/free-solid-svg-icons": "^6.4.0",
54
+ "broccoli-funnel": "^3.0.8",
55
+ "ember-cli-babel": "^8.2.0",
56
+ "ember-cli-htmlbars": "^6.3.0",
57
+ "ember-intl": "6.3.2",
58
+ "ember-radio-button": "^3.0.0-beta.1",
59
+ "ember-wormhole": "^0.6.0"
60
+ },
61
+ "devDependencies": {
62
+ "@babel/eslint-parser": "^7.22.15",
63
+ "@babel/plugin-proposal-decorators": "^7.23.2",
64
+ "@ember/optional-features": "^2.0.0",
65
+ "@ember/test-helpers": "^3.2.0",
66
+ "@embroider/test-setup": "^3.0.2",
67
+ "@glimmer/component": "^1.1.2",
68
+ "@glimmer/tracking": "^1.1.2",
69
+ "broccoli-asset-rev": "^3.0.0",
70
+ "concurrently": "^8.2.2",
71
+ "ember-auto-import": "^2.6.3",
72
+ "ember-cli": "~5.4.1",
73
+ "ember-cli-clean-css": "^3.0.0",
74
+ "ember-cli-dependency-checker": "^3.3.2",
75
+ "ember-cli-inject-live-reload": "^2.1.0",
76
+ "ember-cli-sri": "^2.1.1",
77
+ "ember-cli-terser": "^4.0.2",
78
+ "ember-composable-helpers": "^5.0.0",
79
+ "ember-concurrency": "^2.3.7",
80
+ "ember-concurrency-decorators": "^2.0.3",
81
+ "ember-data": "~5.3.0",
82
+ "ember-engines": "^0.9.0",
83
+ "ember-load-initializers": "^2.1.2",
84
+ "ember-math-helpers": "^4.0.0",
85
+ "ember-page-title": "^8.0.0",
86
+ "ember-qunit": "^8.0.1",
87
+ "ember-resolver": "^11.0.1",
88
+ "ember-source": "~5.4.0",
89
+ "ember-source-channel-url": "^3.0.0",
90
+ "ember-template-lint": "^5.11.2",
91
+ "ember-try": "^3.0.0",
92
+ "eslint": "^8.52.0",
93
+ "eslint-config-prettier": "^9.0.0",
94
+ "eslint-plugin-ember": "^11.11.1",
95
+ "eslint-plugin-n": "^16.2.0",
96
+ "eslint-plugin-prettier": "^5.0.1",
97
+ "eslint-plugin-qunit": "^8.0.1",
98
+ "loader.js": "^4.7.0",
99
+ "prettier": "^3.0.3",
100
+ "qunit": "^2.20.0",
101
+ "qunit-dom": "^2.0.0",
102
+ "stylelint": "^15.11.0",
103
+ "stylelint-config-standard": "^34.0.0",
104
+ "stylelint-prettier": "^4.0.2",
105
+ "webpack": "^5.89.0"
106
+ },
107
+ "peerDependencies": {
108
+ "ember-engines": "^0.9.0"
109
+ },
110
+ "engines": {
111
+ "node": ">= 18"
112
+ },
113
+ "ember": {
114
+ "edition": "octane"
115
+ },
116
+ "ember-addon": {
117
+ "configPath": "tests/dummy/config"
118
+ },
119
+ "prettier": {
120
+ "trailingComma": "es5",
121
+ "tabWidth": 4,
122
+ "semi": true,
123
+ "singleQuote": true,
124
+ "printWidth": 190,
125
+ "overrides": [
126
+ {
127
+ "files": "*.hbs",
128
+ "options": {
129
+ "singleQuote": false
130
+ }
131
+ }
132
+ ]
133
+ }
134
+ }
@@ -0,0 +1,8 @@
1
+ parameters:
2
+ level: max
3
+ paths:
4
+ - server/src
5
+
6
+ checkMissingIterableValueType: true
7
+ checkGenericClassInNonGenericObjectType: false
8
+ reportUnmatchedIgnoredErrors: true
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xsi:noNamespaceSchemaLocation="./server_vendor/phpunit/phpunit/phpunit.xsd"
4
+ colors="true"
5
+ >
6
+ <testsuites>
7
+ <testsuite name="default">
8
+ <directory suffix=".php">./server/tests</directory>
9
+ </testsuite>
10
+ </testsuites>
11
+ <filter>
12
+ <whitelist processUncoveredFilesFromWhitelist="true">
13
+ <directory suffix=".php">./server/src</directory>
14
+ </whitelist>
15
+ </filter>
16
+ </phpunit>
@@ -0,0 +1,21 @@
1
+ <?php
2
+
3
+ /**
4
+ * -------------------------------------------
5
+ * Fleetbase Core API Configuration
6
+ * -------------------------------------------
7
+ */
8
+ return [
9
+ 'api' => [
10
+ 'version' => '0.0.1',
11
+ 'routing' => [
12
+ 'prefix' => 'solid',
13
+ 'internal_prefix' => 'int'
14
+ ],
15
+ ],
16
+ 'server' => [
17
+ 'host' => env('SOLID_HOST', 'http://solid'),
18
+ 'port' => (int) env('SOLID_PORT', 3000),
19
+ 'secure' => (bool) env('SOLID_SECURE', false)
20
+ ]
21
+ ];
@@ -0,0 +1,33 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration
8
+ {
9
+ /**
10
+ * Run the migrations.
11
+ */
12
+ public function up(): void
13
+ {
14
+ Schema::create('solid_identities', function (Blueprint $table) {
15
+ $table->id();
16
+ $table->uuid('uuid')->nullable()->index();
17
+ $table->foreignUuid('company_uuid')->nullable()->index()->references('uuid')->on('companies');
18
+ $table->foreignUuid('user_uuid')->nullable()->index()->references('uuid')->on('users');
19
+ $table->string('identifier')->nullable();
20
+ $table->json('token_response')->nullable();
21
+ $table->timestamps();
22
+ $table->softDeletes();
23
+ });
24
+ }
25
+
26
+ /**
27
+ * Reverse the migrations.
28
+ */
29
+ public function down(): void
30
+ {
31
+ Schema::dropIfExists('solid_identities');
32
+ }
33
+ };
@@ -0,0 +1,217 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Solid\Client;
4
+
5
+ use Fleetbase\Solid\Models\SolidIdentity;
6
+ use Illuminate\Http\Client\Response;
7
+ use Illuminate\Support\Facades\Redis;
8
+ use Illuminate\Support\Str;
9
+ use Jumbojett\OpenIDConnectClient as BaseOpenIDConnectClient;
10
+ use Jumbojett\OpenIDConnectClientException;
11
+
12
+ const CLIENT_NAME = 'Fleetbase';
13
+ final class OpenIDConnectClient extends BaseOpenIDConnectClient
14
+ {
15
+ private ?SolidClient $solid;
16
+ private ?SolidIdentity $identity;
17
+ private ?\stdClass $openIdConfig;
18
+
19
+ public function __construct(array $options = [])
20
+ {
21
+ $this->solid = data_get($options, 'solid');
22
+ $this->identity = data_get($options, 'identity');
23
+ if ($this->identity instanceof SolidIdentity) {
24
+ $this->setRedirectURL($this->identity->getRedirectUri());
25
+ }
26
+ $this->setCodeChallengeMethod('S256');
27
+ $this->setClientName(data_get($options, 'clientName', CLIENT_NAME));
28
+ $this->setClientID(data_get($options, 'clientID'));
29
+ $this->setClientSecret(data_get($options, 'clientSecret'));
30
+
31
+ // Restore client credentials
32
+ if (isset($options['restore'])) {
33
+ $this->restoreClientCredentials();
34
+ }
35
+ }
36
+
37
+ public static function create(array $options = []): OpenIDConnectClient
38
+ {
39
+ $client = new static($options);
40
+ $openIdConfig = $client->getOpenIdConfiguration();
41
+ $client->setProviderURL($openIdConfig->issuer);
42
+ $client->setIssuer($openIdConfig->issuer);
43
+ $client->providerConfigParam((array) $openIdConfig);
44
+
45
+ return $client;
46
+ }
47
+
48
+ public function register(array $options = []): OpenIDConnectClient
49
+ {
50
+ // Get registration options
51
+ $clientName = (string) data_get($options, 'clientName', CLIENT_NAME);
52
+ $requestParams = (array) data_get($options, 'requestParams', []);
53
+ $requestOptions = (array) data_get($options, 'requestOptions', []);
54
+ $redirectUri = (string) data_get($options, 'redirectUri', $this->identity ? $this->identity->getRedirectUri() : null);
55
+ $saveCredentials = (bool) data_get($options, 'saveCredentials', false);
56
+ $withCredentials = data_get($options, 'withCredentials');
57
+
58
+ // Get OIDC Config and Registration URL
59
+ $openIdConfig = $this->getOpenIdConfiguration();
60
+
61
+ // Setup OIDC Client
62
+ $this->setIssuer($openIdConfig->issuer);
63
+ $this->providerConfigParam((array) $openIdConfig);
64
+ $this->setRedirectURL($redirectUri);
65
+
66
+ // Get Registration URL
67
+ $registrationUrl = $openIdConfig->registration_endpoint;
68
+
69
+ // Request registration for Client which should handle authentication
70
+ $registrationResponse = $this->solid->post($registrationUrl, ['client_name' => $clientName, 'redirect_uris' => [$redirectUri], ...$requestParams], $requestOptions);
71
+ if ($registrationResponse->successful()) {
72
+ $clientCredentials = (object) $registrationResponse->json();
73
+ $this->setClientCredentials($clientName, $clientCredentials, $saveCredentials, $withCredentials);
74
+ } else {
75
+ throw new OpenIDConnectClientException('Error registering: Please contact the OpenID Connect provider and obtain a Client ID and Secret directly from them');
76
+ }
77
+
78
+ return $this;
79
+ }
80
+
81
+ public function authenticate(): bool
82
+ {
83
+ $this->setCodeChallengeMethod('S256');
84
+ $this->addScope(['openid', 'webid', 'offline_access']);
85
+
86
+ return parent::authenticate();
87
+ }
88
+
89
+ private function setClientCredentials(string $clientName = CLIENT_NAME, $clientCredentials, bool $save = false, \Closure $callback = null): OpenIDConnectClient
90
+ {
91
+ $this->setClientID($clientCredentials->client_id);
92
+ $this->setClientName($clientCredentials->client_name);
93
+ $this->setClientSecret($clientCredentials->client_secret);
94
+
95
+ // Save the client credentials
96
+ if ($save) {
97
+ $this->saveClientCredentials($clientName, $clientCredentials);
98
+ }
99
+
100
+ // Run callback if provided
101
+ if (is_callable($callback)) {
102
+ $callback($clientCredentials);
103
+ }
104
+
105
+ return $this;
106
+ }
107
+
108
+ private function saveClientCredentials(string $clientName = CLIENT_NAME, $clientCredentials): OpenIDConnectClient
109
+ {
110
+ $key = $this->getClientCredentialsKey($clientName);
111
+
112
+ return $this->save($key, $clientCredentials);
113
+ }
114
+
115
+ public function restoreClientCredentials(string $clientName = CLIENT_NAME, array $overwrite = []): OpenIDConnectClient
116
+ {
117
+ $key = $this->getClientCredentialsKey($clientName);
118
+ $savedClientCredentials = $this->retrieve($key);
119
+ if (!$savedClientCredentials) {
120
+ throw new \Exception('No saved client credentials to restore.');
121
+ }
122
+
123
+ $restoredClientCredentials = (object) array_merge((array) $savedClientCredentials, $overwrite);
124
+ $this->setClientCredentials($clientName, $restoredClientCredentials);
125
+
126
+ return $this;
127
+ }
128
+
129
+ private function getClientCredentialsKey(string $clientName = CLIENT_NAME): string
130
+ {
131
+ if ($this->identity instanceof SolidIdentity) {
132
+ return 'oidc:client_credentials:' . Str::slug($clientName) . ':' . $this->identity->uuid;
133
+ }
134
+
135
+ return 'oidc:client_credentials:' . Str::slug($clientName);
136
+ }
137
+
138
+ private function save(string $key, $value): OpenIDConnectClient
139
+ {
140
+ if (is_object($value) || is_array($value)) {
141
+ $value = json_encode($value);
142
+ }
143
+
144
+ Redis::set($key, $value);
145
+
146
+ return $this;
147
+ }
148
+
149
+ private function retrieve(string $key)
150
+ {
151
+ $value = Redis::get($key);
152
+ if (Str::isJson($value)) {
153
+ $value = (object) json_decode($value);
154
+ }
155
+
156
+ return $value;
157
+ }
158
+
159
+ public function getOpenIdConfiguration(string $key = null)
160
+ {
161
+ $openIdConfigResponse = $this->solid->get('.well-known/openid-configuration');
162
+ if ($openIdConfigResponse instanceof Response) {
163
+ $openIdConfig = (object) $openIdConfigResponse->json();
164
+ if ($key) {
165
+ return $openIdConfig->{$key};
166
+ }
167
+
168
+ $this->openIdConfig = $openIdConfig;
169
+
170
+ return $openIdConfig;
171
+ }
172
+
173
+ return null;
174
+ }
175
+
176
+ protected function getSessionKey($key)
177
+ {
178
+ if (Redis::exists('oidc:session' . Str::slug($key))) {
179
+ return $this->retrieve('oidc:session' . Str::slug($key));
180
+ }
181
+
182
+ return false;
183
+ }
184
+
185
+ protected function setSessionKey($key, $value)
186
+ {
187
+ $this->save('oidc:session' . Str::slug($key), $value);
188
+ }
189
+
190
+ protected function unsetSessionKey($key)
191
+ {
192
+ Redis::del('oidc:session' . Str::slug($key));
193
+ }
194
+
195
+ protected function getAllSessionKeysWithValues()
196
+ {
197
+ $pattern = 'oidc:session*'; // Pattern to match keys
198
+ $keys = [];
199
+ $cursor = 0;
200
+
201
+ do {
202
+ // Use the SCAN command to find keys matching the pattern
203
+ [$cursor, $results] = Redis::scan($cursor, 'MATCH', $pattern);
204
+
205
+ foreach ($results as $key) {
206
+ // Retrieve each value and add it to the keys array
207
+ $keys[$key] = Redis::get($key);
208
+ }
209
+ } while ($cursor);
210
+
211
+ return $keys;
212
+ }
213
+
214
+ // public static function createDPoP(string $method, string $url, string $accessToken = null): string
215
+ // {
216
+ // }
217
+ }
@@ -0,0 +1,186 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Solid\Client;
4
+
5
+ use Fleetbase\Solid\Models\SolidIdentity;
6
+ use Illuminate\Http\Client\Response;
7
+ use Illuminate\Support\Facades\Http;
8
+ use Illuminate\Support\Str;
9
+
10
+ class SolidClient
11
+ {
12
+ private string $host = 'localhost';
13
+ private int $port = 3000;
14
+ private bool $secure = true;
15
+ public ?SolidIdentity $solidIdentity;
16
+ public ?OpenIDConnectClient $oidc;
17
+ private const DEFAULT_MIME_TYPE = 'text/turtle';
18
+ private const LDP_BASIC_CONTAINER = 'http://www.w3.org/ns/ldp#BasicContainer';
19
+ private const LDP_RESOURCE = 'http://www.w3.org/ns/ldp#Resource';
20
+ private const OIDC_ISSUER = 'http://www.w3.org/ns/solid/terms#oidcIssuer';
21
+
22
+ /**
23
+ * Constructor for the SolidClient.
24
+ *
25
+ * Initializes the client with the provided options or defaults.
26
+ *
27
+ * @param array $options configuration options for the client
28
+ */
29
+ public function __construct(array $options = [])
30
+ {
31
+ $this->identity = data_get($options, 'identity');
32
+ $this->host = config('solid.server.host', data_get($options, 'host'));
33
+ $this->port = (int) config('solid.server.port', data_get($options, 'port'));
34
+ $this->secure = (bool) config('solid.server.secure', data_get($options, 'secure'));
35
+ $this->oidc = OpenIDConnectClient::create(['solid' => $this, ...$options]);
36
+ }
37
+
38
+ /**
39
+ * Factory method to create a new instance of the SolidClient.
40
+ *
41
+ * @param array $options configuration options for the client
42
+ *
43
+ * @return static a new instance of SolidClient
44
+ */
45
+ public static function create(array $options = []): self
46
+ {
47
+ return new static($options);
48
+ }
49
+
50
+ /**
51
+ * Constructs the URL to the Solid server based on the configured host, port, and security.
52
+ *
53
+ * @return string the fully constructed URL
54
+ */
55
+ public function getServerUrl(): string
56
+ {
57
+ $protocol = $this->secure ? 'https' : 'http';
58
+ $host = preg_replace('#^.*://#', '', $this->host);
59
+
60
+ return "{$protocol}://{$host}:{$this->port}";
61
+ }
62
+
63
+ /**
64
+ * Creates a full request URL based on the server URL and the provided URI.
65
+ *
66
+ * This function constructs a complete URL by appending the given URI to the base server URL.
67
+ * It ensures that there is exactly one slash between the base URL and the URI.
68
+ *
69
+ * @param string|null $uri The URI to append to the server URL. If null, only the server URL is returned.
70
+ *
71
+ * @return string the fully constructed URL
72
+ */
73
+ private function createRequestUrl(string $uri = null): string
74
+ {
75
+ if (Str::startsWith($uri, 'http')) {
76
+ return $uri;
77
+ }
78
+
79
+ $url = $this->getServerUrl();
80
+ if (is_string($uri)) {
81
+ $uri = '/' . ltrim($uri, '/');
82
+ $url .= $uri;
83
+ }
84
+
85
+ return $url;
86
+ }
87
+
88
+ /**
89
+ * Set the identity to use for authenticated request.
90
+ */
91
+ public function withIdentity(SolidIdentity $identity): SolidClient
92
+ {
93
+ $this->identity = $identity;
94
+
95
+ return $this;
96
+ }
97
+
98
+ /**
99
+ * Make a HTTP request to the Solid server.
100
+ *
101
+ * @param string $method The HTTP method (GET, POST, etc.)
102
+ * @param string $uri The URI to send the request to
103
+ * @param array $options Options for the request
104
+ */
105
+ protected function request(string $method, string $uri, array $data = [], array $options = []): Response
106
+ {
107
+ $url = $this->createRequestUrl($uri);
108
+
109
+ return Http::withOptions($options)->{$method}($url, $data);
110
+ }
111
+
112
+ /**
113
+ * Send an authenticated request with the current identity.
114
+ */
115
+ public function authenticatedRequest(string $method, string $uri, array $data = [], array $options = []): Response
116
+ {
117
+ if (!$this->identity) {
118
+ throw new \Exception('Solid Identity required to make an authenticated request.');
119
+ }
120
+
121
+ $url = $this->createRequestUrl($uri);
122
+ $accessToken = $this->identity->getAccessToken();
123
+ if ($accessToken) {
124
+ $options['headers'] = is_array($options['headers']) ? $options['headers'] : [];
125
+ $options['headers']['Authorization'] = 'DPoP ' . $accessToken;
126
+ $options['headers']['DPoP'] = OpenIDConnectClient::createDPoP($method, $url, $accessToken);
127
+ }
128
+
129
+ return Http::withOptions($options)->{$method}($url, $data);
130
+ }
131
+
132
+ /**
133
+ * Send a GET request to the Solid server.
134
+ *
135
+ * @param string $uri The URI to send the request to
136
+ * @param array $options Options for the request
137
+ */
138
+ public function get(string $uri, array $data = [], array $options = []): Response
139
+ {
140
+ return $this->request('get', $uri, $data, $options);
141
+ }
142
+
143
+ /**
144
+ * Send a POST request to the Solid server.
145
+ *
146
+ * @param string $uri The URI to send the request to
147
+ * @param array $data Data to be sent in the request body
148
+ */
149
+ public function post(string $uri, array $data = [], array $options = []): Response
150
+ {
151
+ return $this->request('post', $uri, $data, $options);
152
+ }
153
+
154
+ /**
155
+ * Send a PUT request to the Solid server.
156
+ *
157
+ * @param string $uri The URI to send the request to
158
+ * @param array $data Data to be sent in the request body
159
+ */
160
+ public function put(string $uri, array $data = [], array $options = []): Response
161
+ {
162
+ return $this->request('put', $uri, $data, $options);
163
+ }
164
+
165
+ /**
166
+ * Send a PATCH request to the Solid server.
167
+ *
168
+ * @param string $uri The URI to send the request to
169
+ * @param array $data Data to be sent in the request body
170
+ */
171
+ public function patch(string $uri, array $data = [], array $options = []): Response
172
+ {
173
+ return $this->request('patch', $uri, $data, $options);
174
+ }
175
+
176
+ /**
177
+ * Send a DELETE request to the Solid server.
178
+ *
179
+ * @param string $uri The URI to send the request to
180
+ * @param array $options Options for the request
181
+ */
182
+ public function delete(string $uri, array $data = [], array $options = []): Response
183
+ {
184
+ return $this->request('delete', $uri, $data, $options);
185
+ }
186
+ }
@@ -0,0 +1,32 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\Solid\Http\Controllers;
4
+
5
+ use Fleetbase\Http\Controllers\Controller as BaseController;
6
+ use Fleetbase\Solid\Client\SolidClient;
7
+ use Fleetbase\Solid\Models\SolidIdentity;
8
+ use Fleetbase\Support\Utils;
9
+ use Illuminate\Http\Request;
10
+
11
+ class OIDCController extends BaseController
12
+ {
13
+ public function completeRegistration(string $identifier, Request $request)
14
+ {
15
+ if ($request->has('code') && $identifier) {
16
+ try {
17
+ $identity = SolidIdentity::where('identifier', $identifier)->first();
18
+ if ($identity) {
19
+ $solid = SolidClient::create(['identity' => $identity, 'restore' => true]);
20
+ $solid->oidc->authenticate();
21
+ $identity->update(['token_response' => $solid->oidc->getTokenResponse()]);
22
+ }
23
+ } catch (\Throwable $e) {
24
+ return redirect(Utils::consoleUrl('solid-protocol', ['error' => $e->getMessage()]));
25
+ }
26
+
27
+ return redirect(Utils::consoleUrl('solid-protocol', $request->all()));
28
+ }
29
+
30
+ return redirect(Utils::consoleUrl('solid-protocol', ['error' => 'Unable to authenticate with provider']));
31
+ }
32
+ }