Skip to content

Commit 61326f2

Browse files
committed
look for typed services providing Auth2 token/logout (#3789)
- DRY search routines into functions defined in getServices - all routines should look for Auth2 types and Auth1 profiles
1 parent dd09ce7 commit 61326f2

File tree

5 files changed

+138
-17
lines changed

5 files changed

+138
-17
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { v4 as uuid } from 'uuid';
2+
import {
3+
anyAuthServices, getLogoutService, getProbeService, getTokenService,
4+
} from '../../../src/lib/getServices';
5+
6+
/**
7+
*/
8+
function resourceFixtureWithService(props) {
9+
return {
10+
id: uuid(),
11+
services: [
12+
{ ...props },
13+
],
14+
type: 'Dataset',
15+
};
16+
}
17+
18+
/**
19+
*/
20+
function actualLogoutServiceId(resource) {
21+
const service = getLogoutService(resource);
22+
return service
23+
&& service.id;
24+
}
25+
26+
/**
27+
*/
28+
function actualTokenServiceId(resource) {
29+
const service = getTokenService(resource);
30+
return service
31+
&& service.id;
32+
}
33+
34+
/**
35+
*/
36+
function actualProbeServiceId(resource) {
37+
const service = getProbeService(resource);
38+
return service
39+
&& service.id;
40+
}
41+
42+
describe('anyAuthServices', () => {
43+
it('returns a filtered list', () => {
44+
const serviceId = uuid();
45+
const auth0 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/0/anyService' });
46+
expect(anyAuthServices(auth0).length).toEqual(1);
47+
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/anyService' });
48+
expect(anyAuthServices(auth1).length).toEqual(1);
49+
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthAnyService2' });
50+
expect(anyAuthServices(auth2).length).toEqual(1);
51+
const notAuthProfile = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/not-auth/1/anyService' });
52+
expect(anyAuthServices(notAuthProfile).length).toEqual(0);
53+
const notAuthType = resourceFixtureWithService({ id: serviceId, type: 'NotAuthAnyService2' });
54+
expect(anyAuthServices(notAuthType).length).toEqual(0);
55+
});
56+
});
57+
58+
describe('getLogoutService', () => {
59+
it('returns a Service', () => {
60+
const serviceId = uuid();
61+
const auth0 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/0/logout' });
62+
expect(actualLogoutServiceId(auth0)).toEqual(serviceId);
63+
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/logout' });
64+
expect(actualLogoutServiceId(auth1)).toEqual(serviceId);
65+
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthLogoutService2' });
66+
expect(actualLogoutServiceId(auth2)).toEqual(serviceId);
67+
});
68+
});
69+
70+
describe('getProbeService', () => {
71+
it('returns a Service', () => {
72+
const serviceId = uuid();
73+
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthProbeService2' });
74+
expect(actualProbeServiceId(auth2)).toEqual(serviceId);
75+
});
76+
});
77+
78+
describe('getTokenService', () => {
79+
it('returns a Service', () => {
80+
const serviceId = uuid();
81+
const auth0 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/0/token' });
82+
expect(actualTokenServiceId(auth0)).toEqual(serviceId);
83+
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/token' });
84+
expect(actualTokenServiceId(auth1)).toEqual(serviceId);
85+
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthAccessTokenService2' });
86+
expect(actualTokenServiceId(auth2)).toEqual(serviceId);
87+
});
88+
});

src/containers/IIIFAuthentication.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { connect } from 'react-redux';
22
import { compose } from 'redux';
33
import { withTranslation } from 'react-i18next';
4-
import { Utils } from 'manifesto.js';
54
import { withPlugins } from '../extend/withPlugins';
5+
import { getLogoutService, getTokenService } from '../lib/getServices';
66
import * as actions from '../state/actions';
77
import {
88
getAuth,
@@ -23,14 +23,8 @@ const mapStateToProps = (state, { windowId }) => {
2323
// TODO: get the most actionable auth service...
2424
const service = services[0];
2525

26-
const accessTokenService = service && (
27-
Utils.getService(service, 'http://iiif.io/api/auth/1/token')
28-
|| Utils.getService(service, 'http://iiif.io/api/auth/0/token')
29-
);
30-
const logoutService = service && (
31-
Utils.getService(service, 'http://iiif.io/api/auth/1/logout')
32-
|| Utils.getService(service, 'http://iiif.io/api/auth/0/logout')
33-
);
26+
const accessTokenService = getTokenService(service);
27+
const logoutService = getLogoutService(service);
3428

3529
const authStatuses = getAuth(state);
3630
const authStatus = service && authStatuses[service.id];

src/lib/getServices.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Utils } from 'manifesto.js';
2+
import { filterByTypes } from './typeFilters';
3+
4+
/**
5+
*/
6+
export function anyAuthServices(resource) {
7+
return resource
8+
&& Utils.getServices(resource).filter(s => (s.getProfile()
9+
&& s.getProfile().match(/http:\/\/iiif.io\/api\/auth\//))
10+
|| (s.getProperty('type')
11+
&& s.getProperty('type').match(/^Auth.*2$/)));
12+
}
13+
14+
/**
15+
*/
16+
export function getProbeService(resource) {
17+
return resource
18+
&& filterByTypes(Utils.getServices(resource), 'AuthProbeService2')[0];
19+
}
20+
21+
/**
22+
*/
23+
export function getTokenService(resource) {
24+
return resource
25+
&& (
26+
Utils.getService(resource, 'http://iiif.io/api/auth/1/token')
27+
|| Utils.getService(resource, 'http://iiif.io/api/auth/0/token')
28+
|| filterByTypes(Utils.getServices(resource), 'AuthAccessTokenService2')[0]
29+
);
30+
}
31+
32+
/**
33+
*/
34+
export function getLogoutService(resource) {
35+
return resource
36+
&& (
37+
Utils.getService(resource, 'http://iiif.io/api/auth/1/logout')
38+
|| Utils.getService(resource, 'http://iiif.io/api/auth/0/logout')
39+
|| filterByTypes(Utils.getServices(resource), 'AuthLogoutService2')[0]
40+
);
41+
}

src/state/sagas/auth.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Utils } from 'manifesto.js';
55
import flatten from 'lodash/flatten';
66
import ActionTypes from '../actions/action-types';
77
import MiradorCanvas from '../../lib/MiradorCanvas';
8+
import { getTokenService } from '../../lib/getServices';
89
import {
910
addAuthenticationRequest,
1011
resolveAuthenticationRequest,
@@ -52,8 +53,7 @@ export function* refetchInfoResponses({ serviceId }) {
5253
const haveThisTokenService = infoResponse => {
5354
const services = Utils.getServices(infoResponse);
5455
return services.some(e => {
55-
const infoTokenService = Utils.getService(e, 'http://iiif.io/api/auth/1/token')
56-
|| Utils.getService(e, 'http://iiif.io/api/auth/0/token');
56+
const infoTokenService = getTokenService(e);
5757
return infoTokenService && infoTokenService.id === serviceId;
5858
});
5959
};
@@ -90,8 +90,7 @@ export function* doAuthWorkflow({ infoJson, windowId }) {
9090
// start the auth
9191
yield put(addAuthenticationRequest(windowId, authService.id, authService.getProfile()));
9292
} else if (profileConfig.external) {
93-
const tokenService = Utils.getService(authService, 'http://iiif.io/api/auth/1/token')
94-
|| Utils.getService(authService, 'http://iiif.io/api/auth/0/token');
93+
const tokenService = getTokenService(authService);
9594

9695
if (!tokenService) return;
9796
// resolve the auth
@@ -107,8 +106,7 @@ export function* rerequestOnAccessTokenFailure({ infoJson, windowId, tokenServic
107106

108107
// make sure we have an auth service to try
109108
const authService = Utils.getServices(infoJson).find(service => {
110-
const tokenService = Utils.getService(service, 'http://iiif.io/api/auth/1/token')
111-
|| Utils.getService(service, 'http://iiif.io/api/auth/0/token');
109+
const tokenService = getTokenService(service);
112110

113111
return tokenService && tokenService.id === tokenServiceId;
114112
});

src/state/sagas/iiif.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
receiveSearch, receiveSearchFailure,
1111
receiveAnnotation, receiveAnnotationFailure,
1212
} from '../actions';
13+
import { getTokenService } from '../../lib/getServices';
1314
import {
1415
getManifests,
1516
getRequestsConfig,
@@ -128,8 +129,7 @@ function* getAccessTokenService(resource) {
128129

129130
for (let i = 0; i < services.length; i += 1) {
130131
const authService = services[i];
131-
const accessTokenService = Utils.getService(authService, 'http://iiif.io/api/auth/1/token')
132-
|| Utils.getService(authService, 'http://iiif.io/api/auth/0/token');
132+
const accessTokenService = getTokenService(authService);
133133
const token = accessTokenService && accessTokens[accessTokenService.id];
134134
if (token && token.json) return token;
135135
}

0 commit comments

Comments
 (0)