Skip to content

Commit

Permalink
feat(seeding): Add seeding as a default initializer, update seeded po…
Browse files Browse the repository at this point in the history
…d copy and guide, change seeded pod config to array
  • Loading branch information
adlerfaulkner committed Mar 7, 2022
1 parent 27a7fe7 commit 2dd0603
Show file tree
Hide file tree
Showing 20 changed files with 138 additions and 138 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ to some commonly used settings:
| `--sparqlEndpoint, -s` | | URL of the SPARQL endpoint, when using a quadstore-based configuration. |
| `--showStackTrace, -t` | false | Enables detailed logging on error pages. |
| `--podConfigJson` | `./pod-config.json` | Path to the file that keeps track of dynamic Pod configurations. |
| `--seededPodConfigJson` | `./seeded-pod-config.json` | Path to the file that keeps track of seeded Pod configurations. |
| `--seededPodConfigJson` | | Path to the file that keeps track of seeded Pod configurations. |
| `--mainModulePath, -m` | | Path from where Components.js will start its lookup when initializing configurations.

### 🧶 Custom configurations
Expand Down
17 changes: 0 additions & 17 deletions config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,3 @@ but instead have the following in your root config:
```
Don't forget that in some cases you would also have to copy some imports!
The existing options can be used as inspiration.

# How to seed Accounts/Pods
If you need to seed accounts and pods, use the `file-seeded.json` config
via `-c config/file-seeded.json` when starting your server. The config will by
default read `./seeded-pod-config.json` to set your desired accounts and pods.
You can modify the name and path of the seed file by setting the `--seededPodConfigJson`
option. `./seeded-pod-config.json` should be a JSON object whose values include
`podName`, `email`, and `password`. For example:
```json
{
"example": {
"podName": "example",
"email": "hello@example.com",
"password": "abc123"
}
}
```
2 changes: 2 additions & 0 deletions config/app/init/base/init.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"files-scs:config/app/init/initializers/base-url.json",
"files-scs:config/app/init/initializers/logger.json",
"files-scs:config/app/init/initializers/server.json",
"files-scs:config/app/init/initializers/seeded-pod.json",
"files-scs:config/app/init/initializers/version.json"
],
"@graph": [
Expand All @@ -15,6 +16,7 @@
{ "@id": "urn:solid-server:default:LoggerInitializer" },
{ "@id": "urn:solid-server:default:BaseUrlVerifier" },
{ "@id": "urn:solid-server:default:ParallelInitializer" },
{ "@id": "urn:solid-server:default:SeededPodInitializer" },
{ "@id": "urn:solid-server:default:ServerInitializer" },
{ "@id": "urn:solid-server:default:ModuleVersionVerifier" }
]
Expand Down
17 changes: 0 additions & 17 deletions config/app/init/initialize-seeded-root.json

This file was deleted.

23 changes: 23 additions & 0 deletions config/app/init/initializers/seeded-pod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^3.0.0/components/context.jsonld",
"@graph": [
{
"comment": "Separate manager from the RegistrationHandler in case registration is disabled.",
"@id": "urn:solid-server:default:SeededPodRegistrationManager",
"@type": "RegistrationManager",
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
"args_webIdSuffix": "/profile/card#me",
"args_identifierGenerator": { "@id": "urn:solid-server:default:IdentifierGenerator" },
"args_ownershipValidator": { "@id": "urn:solid-server:auth:password:OwnershipValidator" },
"args_accountStore": { "@id": "urn:solid-server:auth:password:AccountStore" },
"args_podManager": { "@id": "urn:solid-server:default:PodManager" }
},
{
"comment": "Initializer that instantiates all the seeded accounts and pods.",
"@id": "urn:solid-server:default:SeededPodInitializer",
"@type": "SeededPodInitializer",
"registrationManager": { "@id": "urn:solid-server:default:SeededPodRegistrationManager" },
"configFilePath": { "@id": "urn:solid-server:default:variable:seededPodConfigJson" },
}
]
}
38 changes: 0 additions & 38 deletions config/app/init/initializers/seeded-root.json

This file was deleted.

2 changes: 1 addition & 1 deletion config/app/variables/cli/cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"seededPodConfigJson": {
"requiresArg": true,
"type": "string",
"describe": "Path to the file that keeps track of seeded Pod configurations."
"describe": "Path to the file that will be used to seed pods."
}
},
"options": {
Expand Down
3 changes: 1 addition & 2 deletions config/app/variables/resolver/resolver.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@
"CombinedSettingsResolver:_computers_key": "urn:solid-server:default:variable:seededPodConfigJson",
"CombinedSettingsResolver:_computers_value": {
"@type": "AssetPathExtractor",
"key": "seededPodConfigJson",
"defaultPath": "./seeded-pod-config.json"
"key": "seededPodConfigJson"
}
}
]
Expand Down
8 changes: 4 additions & 4 deletions config/file-seeded.json → config/custom.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^3.0.0/components/context.jsonld",
"import": [
"files-scs:config/app/main/default.json",
"files-scs:config/app/init/initialize-seeded-root.json",
"files-scs:config/app/init/initialize-dgraph-seeded-root.json",
"files-scs:config/app/setup/disabled.json",
"files-scs:config/app/variables/default.json",
"files-scs:config/http/handler/default.json",
Expand All @@ -21,8 +21,8 @@
"files-scs:config/ldp/metadata-parser/default.json",
"files-scs:config/ldp/metadata-writer/default.json",
"files-scs:config/ldp/modes/default.json",
"files-scs:config/storage/backend/file.json",
"files-scs:config/storage/key-value/resource-store.json",
"files-scs:config/storage/backend/dgraph.json",
"files-scs:config/storage/key-value/memory.json",
"files-scs:config/storage/middleware/default.json",
"files-scs:config/util/auxiliary/acl.json",
"files-scs:config/util/identifiers/suffix.json",
Expand All @@ -34,7 +34,7 @@
],
"@graph": [
{
"comment": "A single-pod server that stores its resources on disk."
"comment": "A pod server that stores its resources in a dgraph database."
}
]
}
2 changes: 1 addition & 1 deletion config/util/variables/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@type": "Variable"
},
{
"comment": "Path to the JSON file used to store configuration for seeded pods.",
"comment": "Path to the JSON file used to seed pods.",
"@id": "urn:solid-server:default:variable:seededPodConfigJson",
"@type": "Variable"
}
Expand Down
25 changes: 25 additions & 0 deletions guides/seeding-pods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# How to seed Accounts and Pods
If you need to seed accounts and pods, set the `--seededPodConfigJson` option to a file such as `./seeded-pod-config.json` to set your desired accounts and pods. The contents of `./seeded-pod-config.json` (or whatever file name you choose) should be a JSON array whose entries are objects which include
`podName`, `email`, and `password`. For example:
```json
[
{
"podName": "example",
"email": "hello@example.com",
"password": "abc123"
}
]
```

You may optionally specify other parameters accepted by the `register` method of [RegistrationManager](https://github.com/solid/community-server/blob/3b353affb1f0919fdcb66172364234eb59c2e3f6/src/identity/interaction/email-password/util/RegistrationManager.ts#L173). For example:

To use a pre-existing wedId:
```json
createWebId: false,
webId: "https://pod.inrupt.com/example/profile/card#me"
```

To use a specific pod template:
```json
template: "./templates/custom_pod_template"
```
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,10 @@ export * from './init/AppRunner';
export * from './init/BaseUrlVerifier';
export * from './init/CliResolver';
export * from './init/ConfigPodInitializer';
export * from './init/SeededPodInitializer';
export * from './init/ContainerInitializer';
export * from './init/Initializer';
export * from './init/LoggerInitializer';
export * from './init/SeededPodInitializer';
export * from './init/ServerInitializer';
export * from './init/ModuleVersionVerifier';

Expand Down
68 changes: 32 additions & 36 deletions src/init/SeededPodInitializer.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,51 @@
import { promises as fsPromises } from 'fs';
import type { RegistrationManager } from '../identity/interaction/email-password/util/RegistrationManager';
import { getLoggerFor } from '../logging/LogUtil';
import type { KeyValueStorage } from '../storage/keyvalue/KeyValueStorage';
import { Initializer } from './Initializer';

export interface SeederPodInitializerArgs {
/**
* Used for registering seeded pods.
*/
registrationManager: RegistrationManager;
/**
* Settings that the seeded Pods should be created with.
*/
configStorage: KeyValueStorage<string, unknown>;
}

/**
* Uses a {@link RegistrationManager} to initializes accounts and pods
* Uses a {@link RegistrationManager} to initialize accounts and pods
* for all seeded pods. Reads the pod settings from seededPodConfigJson.
*/
export class SeededPodInitializer extends Initializer {
protected readonly logger = getLoggerFor(this);

private readonly registrationManager: RegistrationManager;
private readonly configStorage: KeyValueStorage<string, unknown>;
private readonly configFilePath: string | null;

public constructor(args: SeederPodInitializerArgs) {
public constructor(registrationManager: RegistrationManager, configFilePath: string | null) {
super();
this.registrationManager = args.registrationManager;
this.configStorage = args.configStorage;
this.registrationManager = registrationManager;
this.configFilePath = configFilePath;
}

public async handle(): Promise<void> {
let count = 0;
for await (const [ , value ] of this.configStorage.entries()) {
const config = value as NodeJS.Dict<unknown>;
config.confirmPassword = config.password;
config.createPod = true;
config.createWebId = true;
config.register = true;

this.logger.info(`Initializing pod ${config.podName}`);

// Validate the input JSON
const validated = this.registrationManager.validateInput(config, true);
this.logger.debug(`Validated input: ${JSON.stringify(validated)}`);

// Register and/or create a pod as requested. Potentially does nothing if all booleans are false.
await this.registrationManager.register(validated, true);
this.logger.info(`Initialized seeded pod and account for "${config.podName}".`);
count += 1;
if (this.configFilePath) {
const configText = await fsPromises.readFile(this.configFilePath, 'utf8');
const configuration: NodeJS.Dict<unknown>[] = JSON.parse(configText);

let count = 0;
for await (const input of configuration) {
const config = {
confirmPassword: input.password,
createPod: true,
createWebId: true,
register: true,
...input,
};

this.logger.info(`Initializing pod ${input.podName}`);

// Validate the input JSON
const validated = this.registrationManager.validateInput(config, true);
this.logger.debug(`Validated input: ${JSON.stringify(validated)}`);

// Register and/or create a pod as requested. Potentially does nothing if all booleans are false.
await this.registrationManager.register(validated, true);
this.logger.info(`Initialized seeded pod and account for "${input.podName}".`);
count += 1;
}
this.logger.info(`Initialized ${count} seeded pods.`);
}
this.logger.info(`Initialized ${count} seeded pods.`);
}
}
11 changes: 8 additions & 3 deletions src/init/variables/extractors/AssetPathExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ export class AssetPathExtractor extends SettingsExtractor {

public async handle(args: Settings): Promise<unknown> {
const path = args[this.key] ?? this.defaultPath;
if (typeof path !== 'string') {
throw new Error(`Invalid ${this.key} argument`);
if (path) {
if (typeof path !== 'string') {
throw new Error(`Invalid ${this.key} argument`);
}

return resolveAssetPath(path);
}
return resolveAssetPath(path);

return null;
}
}
1 change: 1 addition & 0 deletions test/integration/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export function getDefaultVariables(port: number, baseUrl?: string): Record<stri
'urn:solid-server:default:variable:port': port,
'urn:solid-server:default:variable:loggingLevel': 'off',
'urn:solid-server:default:variable:showStackTrace': true,
'urn:solid-server:default:variable:seededPodConfigJson': null,
};
}
1 change: 1 addition & 0 deletions test/integration/WebSocketsProtocol.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('A server with the Solid WebSockets API behind a proxy', (): void => {
getTestConfigPath('server-without-auth.json'),
getDefaultVariables(port, 'https://example.pod/'),
) as App;

await app.start();
});

Expand Down
2 changes: 2 additions & 0 deletions test/integration/config/ldp-with-auth.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"files-scs:config/http/static/default.json",
"files-scs:config/identity/access/public.json",
"files-scs:config/identity/handler/default.json",
"files-scs:config/identity/ownership/token.json",
"files-scs:config/identity/pod/static.json",
"files-scs:config/ldp/authentication/debug-auth-header.json",
"files-scs:config/ldp/authorization/webacl.json",
"files-scs:config/ldp/handler/default.json",
Expand Down
3 changes: 3 additions & 0 deletions test/integration/config/server-without-auth.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"files-scs:config/http/middleware/websockets.json",
"files-scs:config/http/server-factory/websockets.json",
"files-scs:config/http/static/default.json",
"files-scs:config/identity/handler/account-store/default.json",
"files-scs:config/identity/ownership/unsafe-no-check.json",
"files-scs:config/identity/pod/static.json",
"files-scs:config/ldp/authentication/dpop-bearer.json",
"files-scs:config/ldp/authorization/allow-all.json",
"files-scs:config/ldp/handler/default.json",
Expand Down
Loading

0 comments on commit 2dd0603

Please sign in to comment.