Skip to content

Commit

Permalink
Merge pull request #865 from koopjs/auth-refactor
Browse files Browse the repository at this point in the history
Provider-based authorization, updates to geoservice auth routes
  • Loading branch information
rgwozdz authored Nov 26, 2023
2 parents c8bb758 + 1d72b58 commit be22508
Show file tree
Hide file tree
Showing 23 changed files with 733 additions and 429 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-rocks-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@koopjs/featureserver': minor
---

- add owningSystemUrl to restInfo response
7 changes: 7 additions & 0 deletions .changeset/fair-mirrors-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@koopjs/koop-core': major
---

- route change in geoservices
- generic plugins and file-system plugins no longer supported
- add option to skip default geoservices plugin
7 changes: 7 additions & 0 deletions .changeset/perfect-feet-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@koopjs/output-geoservices': major
---

- change generateToken route so it matches latest pattern in ArcGIS
- add option "useHttpForTokenUrl" to use http protocol on the authInfo.tokenServicesUrl returned by rest/info route

2 changes: 1 addition & 1 deletion .nycrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"packages/cache-memory/src/**/*.js",
"packages/logger/src/**/*.js",
"packages/output-geoservices/src/**/*.js",
"packages/koop-core/src/**/*.js"
"packages/core/src/**/*.js"
],
"exclude": ["**/*.spec.js"],
"includeAllSources": true
Expand Down
10 changes: 8 additions & 2 deletions demo/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const Koop = require('@koopjs/koop-core');
const provider = require('@koopjs/provider-file-geojson');

const koop = new Koop({ logLevel: 'debug' });

// const auth = require('@koopjs/auth-direct-file')(
// 'pass-in-your-secret',
// `${__dirname}/user-store.json`
// );

// koop.register(auth);
koop.register(provider, { dataDir: './demo/provider-data'});
koop.server.listen(8080);
koop.server.listen(process.env.PORT || 8080);
4 changes: 4 additions & 0 deletions demo/user-store.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[{
"username": "helloworld",
"password": "foobar"
}]
11 changes: 7 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@changesets/changelog-git": "^0.1.14",
"@changesets/cli": "^2.26.2",
"@commitlint/config-conventional": "^18.4.2",
"@koopjs/auth-direct-file": "^2.0.2",
"@koopjs/auth-direct-file": "^3.0.0-alpha.0",
"@koopjs/provider-file-geojson": "^2.2.0",
"await-spawn": "^4.0.2",
"byline": "^5.0.0",
Expand Down
10 changes: 10 additions & 0 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ const options = {
}
```

#### skipGeoservicesRegistration
By default, Koop will register the GeoServices output-plugin (a.k.a. FeatureServer). If you do not want this plugin registered or want to register a specific version, you can skip the default registration by setting the option to `true`:

```js
const options = {
skipGeoservicesRegistration: true
}
```


#### geoservicesDefaults
Koop registers the Geoservices output plugin (FeatureServer) by default. This plugin takes its own options including those to set server and layer metadata (e.g., FeatureServer version, copyrightText, maxRecordCount, etc). These are useful for overriding defaults set in the FeatureServer codebase. You can have Koop set these options at start-up by passing the `geoservicesDefaults` option. It should be a JSON object with the specification described in the [FeatureServer documentation](packages/featureserver#featureserver.setdefaults).

Expand Down
14 changes: 7 additions & 7 deletions packages/core/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 60 additions & 11 deletions packages/core/src/data-provider/extend-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache
}

async pull (req, callback) {
const { error } = await this.#authorizeRequest(req);
if (error) {
return callback(error);
}

const key = this.#createCacheKey(req);

try {
Expand Down Expand Up @@ -63,6 +68,11 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache
// TODO: the pullLayer() and the pullCatalog() are very similar to the pull()
// function. We may consider to merging them in the future.
async pullLayer (req, callback) {
const { error } = await this.#authorizeRequest(req);
if (error) {
return callback(error);
}

if (!this.#getLayer) {
callback(new Error(`getLayer() method is not implemented in the ${this.namespace} provider.`));
}
Expand Down Expand Up @@ -91,6 +101,11 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache
}

async pullCatalog (req, callback) {
const { error } = await this.#authorizeRequest(req);
if (error) {
return callback(error);
}

if (!this.#getCatalog) {
callback(new Error(`getCatalog() method is not implemented in the ${this.namespace} provider.`));
}
Expand Down Expand Up @@ -119,6 +134,12 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache
}

async pullStream (req) {
const { error } = await this.#authorizeRequest(req);

if (error) {
throw error;
}

if (this.getStream) {
await this.#before(req);
const providerStream = await this.getStream(req);
Expand All @@ -135,20 +156,48 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache
}
return hasher(req.url).toString();
}

async #authorizeRequest (req) {
try {
await this.authorize(req);
} catch (error) {
error.code = 401;
return { error };
}

return { error: null };
}
}

// Add auth methods if auth plugin registered with Koop
if (authModule) {
const {
authenticationSpecification,
authenticate,
authorize
} = authModule;

Model.prototype.authenticationSpecification = Object.assign({}, authenticationSpecification(namespace), { provider: namespace });
Model.prototype.authenticate = authenticate;
Model.prototype.authorize = authorize;
// If provider does not have auth-methods,
// check for global auth-module. if exists, use it,
// otherwise use dummy methods

if (typeof ProviderModel.prototype.authorize !== 'function') {
Model.prototype.authorize = typeof authModule?.authorize === 'function' ? authModule.authorize : async () => {};
}

if (typeof ProviderModel.prototype.authenticate !== 'function') {
Model.prototype.authenticate = typeof authModule?.authenticate === 'function' ? authModule?.authenticate : async () => { return {}; };
}

if(typeof authModule?.authenticationSpecification === 'function') {
logger.warn('Use of "authenticationSpecification" is deprecated. It will be removed in a future release.');
Model.prototype.authenticationSpecification = authModule?.authenticationSpecification;
}
// Add auth methods if auth plugin registered with Koop
// if (authModule) {
// const {
// authenticationSpecification,
// authenticate,
// authorize
// } = authModule;

// Model.prototype.authenticationSpecification = Object.assign({}, authenticationSpecification(namespace), { provider: namespace });
// Model.prototype.authenticate = authenticate;
// Model.prototype.authorize = authorize;
// }

return new Model({ logger, cache }, options);
};

Expand Down
Loading

0 comments on commit be22508

Please sign in to comment.