Skip to content

Commit f1d9603

Browse files
committed
feat: local authentication
- introduce passport - add a passport local strategy for authentication - introduce Authentication interface to contain the multiple auth checks (authenticate, checkAuth, logout) - scram router module for authentication, logout, and auth check - no op for no auth - extend auth support to provide additional functions to all modules for checking auth, logging out Contributes-to: strimzi#106 Signed-off-by: Nic Townsend <[email protected]>
1 parent 087cdc3 commit f1d9603

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1339
-406
lines changed

client/Contexts/Introspect/ExpectationTypes.ts

+67-67
Original file line numberDiff line numberDiff line change
@@ -2,130 +2,130 @@
22
* Copyright Strimzi authors.
33
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
44
*/
5-
import {IntrospectionField} from "graphql";
5+
import { IntrospectionField } from 'graphql';
66

77
/**
88
* An expectation is defined per entity we expect e.g. a Topic
99
*/
1010
export interface Expectation {
11+
/**
12+
* The type is the GraphQL type for this expectation
13+
*/
14+
type: string;
15+
/**
16+
* The fields that we expect this entity to have
17+
*/
18+
fields?: {
1119
/**
12-
* The type is the GraphQL type for this expectation
20+
* The field is defined as a GraphQL type
1321
*/
14-
type: string;
22+
[key: string]: string;
23+
};
24+
/**
25+
* The operations that we expect this entity to have
26+
*/
27+
operations?: {
1528
/**
16-
* The fields that we expect this entity to have
29+
* The operation is validated using a callback
1730
*/
18-
fields?: {
19-
/**
20-
* The field is defined as a GraphQL type
21-
*/
22-
[key: string]: string;
23-
};
31+
[key: string]: OperationCallback;
32+
};
33+
/**
34+
* The subscriptions that we expect this entity to have
35+
*/
36+
subscriptions?: {
2437
/**
25-
* The operations that we expect this entity to have
38+
* The subscription is validated using a callback
2639
*/
27-
operations?: {
28-
/**
29-
* The operation is validated using a callback
30-
*/
31-
[key: string]: OperationCallback;
32-
};
33-
/**
34-
* The subscriptions that we expect this entity to have
35-
*/
36-
subscriptions?: {
37-
/**
38-
* The subscription is validated using a callback
39-
*/
40-
[key: string]: SubscriptionCallback;
41-
};
40+
[key: string]: SubscriptionCallback;
41+
};
4242
}
4343

4444
/**
4545
* A collection of expected entities
4646
*/
4747
export interface Expectations {
48-
[key: string]: Expectation;
48+
[key: string]: Expectation;
4949
}
5050

5151
/**
5252
* An entity expresses whether an expectation has been met or not
5353
*/
5454
export interface Entity {
55+
/**
56+
* The type is the GraphQL type for this expectation
57+
*/
58+
type: string;
59+
/**
60+
* The fields that we expect this entity to have
61+
*/
62+
fields: {
5563
/**
56-
* The type is the GraphQL type for this expectation
64+
* Whether the field met the expectation
5765
*/
58-
type: string;
66+
[key: string]: boolean;
67+
};
68+
/**
69+
* The operations that we expect this entity to have
70+
*/
71+
operations: {
5972
/**
60-
* The fields that we expect this entity to have
73+
* Whether the operation met the expectation
6174
*/
62-
fields: {
63-
/**
64-
* Whether the field met the expectation
65-
*/
66-
[key: string]: boolean;
67-
};
75+
[key: string]: boolean;
76+
};
77+
/**
78+
* The subscriptions that we expect this entity to have
79+
*/
80+
subscriptions: {
6881
/**
69-
* The operations that we expect this entity to have
82+
* Whether the subscription met the expectation
7083
*/
71-
operations: {
72-
/**
73-
* Whether the operation met the expectation
74-
*/
75-
[key: string]: boolean;
76-
};
77-
/**
78-
* The subscriptions that we expect this entity to have
79-
*/
80-
subscriptions: {
81-
/**
82-
* Whether the subscription met the expectation
83-
*/
84-
[key: string]: boolean;
85-
};
84+
[key: string]: boolean;
85+
};
8686
}
8787

8888
/**
8989
* The callback properties for an operation expectation
9090
*/
9191
export interface OperationCallbackProps {
92-
/**
93-
* All the queries defined
94-
*/
95-
queries: { [key: string]: IntrospectionField };
96-
/**
97-
* All the mutations defined
98-
*/
99-
mutations: { [key: string]: IntrospectionField };
92+
/**
93+
* All the queries defined
94+
*/
95+
queries: { [key: string]: IntrospectionField };
96+
/**
97+
* All the mutations defined
98+
*/
99+
mutations: { [key: string]: IntrospectionField };
100100
}
101101

102102
/**
103103
* The callback properties for a subscription expectation
104104
*/
105105
export interface SubscriptionCallbackProps {
106-
/**
107-
* All the subscriptions defined
108-
*/
109-
subscriptions: { [key: string]: IntrospectionField };
106+
/**
107+
* All the subscriptions defined
108+
*/
109+
subscriptions: { [key: string]: IntrospectionField };
110110
}
111111

112112
/**
113113
* The callback for an operation expectation
114114
*/
115115
export interface OperationCallback {
116-
(props: OperationCallbackProps): boolean;
116+
(props: OperationCallbackProps): boolean;
117117
}
118118

119119
/**
120120
* The callback for a subscription expectation
121121
*/
122122
export interface SubscriptionCallback {
123-
(props: SubscriptionCallbackProps): boolean;
123+
(props: SubscriptionCallbackProps): boolean;
124124
}
125125

126126
/**
127127
* A collection of entities
128128
*/
129129
export interface Entities {
130-
[key: string]: Entity;
130+
[key: string]: Entity;
131131
}

client/Contexts/Introspect/Introspection.spec.ts

+65-63
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,84 @@
22
* Copyright Strimzi authors.
33
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
44
*/
5-
import expectationsBasic from "./mock/expectations-basic";
6-
import expectationsMissingMutation from "./mock/expectations-missing-mutation";
7-
import introspectionBasic from "./mock/mock-introspection";
5+
import expectationsBasic from './mock/expectations-basic';
6+
import expectationsMissingMutation from './mock/expectations-missing-mutation';
7+
import introspectionBasic from './mock/mock-introspection';
88
import expectionsEmptyTopic from './mock/expectations-empty-topic';
9-
import expectationsMissingType from "./mock/expectations-missing-type"
10-
import introspectionMissingMutation from "./mock/mock-introspection-missing-mutation-type"
11-
import introspectionUnsupportedFieldType from "./mock/mock-introspection-unsupported-field-type";
12-
import introspectionUnindexable from "./mock/mock-introspection-unindexable";
13-
import introspectionMissingMutationBlock from "./mock/mock-introspection-missing-mutation-block";
14-
import introspectionWrongTypeOnTopic from "./mock/mock-introspection-wrong-type-on-topic";
15-
import introspectionWrongTypeOnMutationBlock from "./mock/mock-introspection-wrong-type-on-mutation-block";
16-
import {introspect} from "./Introspection";
17-
import {entitiesBasic} from "./mock/mock-entities";
18-
19-
describe("Basic Introspection", () => {
20-
it("should match", () =>
21-
{
22-
const introspected = introspect(expectationsBasic, introspectionBasic);
23-
expect(introspected).toEqual(entitiesBasic);
24-
});
9+
import expectationsMissingType from './mock/expectations-missing-type';
10+
import introspectionMissingMutation from './mock/mock-introspection-missing-mutation-type';
11+
import introspectionUnsupportedFieldType from './mock/mock-introspection-unsupported-field-type';
12+
import introspectionUnindexable from './mock/mock-introspection-unindexable';
13+
import introspectionMissingMutationBlock from './mock/mock-introspection-missing-mutation-block';
14+
import introspectionWrongTypeOnTopic from './mock/mock-introspection-wrong-type-on-topic';
15+
import introspectionWrongTypeOnMutationBlock from './mock/mock-introspection-wrong-type-on-mutation-block';
16+
import { introspect } from './Introspection';
17+
import { entitiesBasic } from './mock/mock-entities';
18+
19+
describe('Basic Introspection', () => {
20+
it('should match', () => {
21+
const introspected = introspect(expectationsBasic, introspectionBasic);
22+
expect(introspected).toEqual(entitiesBasic);
23+
});
2524
});
2625

27-
describe("Missing Type", () => {
28-
it("should error", () =>
29-
{
30-
expect(() => {introspect(expectationsMissingType, introspectionBasic)}).toThrowError("Unable to find a type for Foo");
31-
32-
});
26+
describe('Missing Type', () => {
27+
it('should error', () => {
28+
expect(() => {
29+
introspect(expectationsMissingType, introspectionBasic);
30+
}).toThrowError('Unable to find a type for Foo');
31+
});
3332
});
3433

35-
describe("Missing Mutation Type", () => {
36-
it("should error", () =>
37-
{
38-
expect(() => {introspect(expectationsMissingMutation, introspectionMissingMutation)}).toThrowError("mutations is empty");
39-
40-
});
34+
describe('Missing Mutation Type', () => {
35+
it('should error', () => {
36+
expect(() => {
37+
introspect(expectationsMissingMutation, introspectionMissingMutation);
38+
}).toThrowError('mutations is empty');
39+
});
4140
});
4241

43-
describe("Unsupported Field Type", () => {
44-
it("should error", () =>
45-
{
46-
expect(() => {introspect(expectationsBasic, introspectionUnsupportedFieldType)}).toThrowError("Unsupported graphql kind UNION for String");
47-
48-
});
42+
describe('Unsupported Field Type', () => {
43+
it('should error', () => {
44+
expect(() => {
45+
introspect(expectationsBasic, introspectionUnsupportedFieldType);
46+
}).toThrowError('Unsupported graphql kind UNION for String');
47+
});
4948
});
5049

51-
describe("Unindexable types", () => {
52-
it("should error", () =>
53-
{
54-
expect(() => {introspect(expectationsBasic, introspectionUnindexable)}).toThrowError("key identified by name must be of type string");
55-
56-
});
50+
describe('Unindexable types', () => {
51+
it('should error', () => {
52+
expect(() => {
53+
introspect(expectationsBasic, introspectionUnindexable);
54+
}).toThrowError('key identified by name must be of type string');
55+
});
5756
});
5857

59-
describe("Missing mutation block", () => {
60-
it("should error", () =>
61-
{
62-
expect(() => {introspect(expectationsBasic, introspectionMissingMutationBlock)}).toThrowError("Unable to find a type for Mutation");
63-
64-
});
58+
describe('Missing mutation block', () => {
59+
it('should error', () => {
60+
expect(() => {
61+
introspect(expectationsBasic, introspectionMissingMutationBlock);
62+
}).toThrowError('Unable to find a type for Mutation');
63+
});
6564
});
6665

67-
describe("Wrong type on mutation block", () => {
68-
it("should error", () =>
69-
{
70-
expect(() => {introspect(expectationsMissingMutation, introspectionWrongTypeOnMutationBlock)}).toThrowError("mutations is empty");
71-
72-
});
66+
describe('Wrong type on mutation block', () => {
67+
it('should error', () => {
68+
expect(() => {
69+
introspect(
70+
expectationsMissingMutation,
71+
introspectionWrongTypeOnMutationBlock
72+
);
73+
}).toThrowError('mutations is empty');
74+
});
7375
});
7476

75-
describe("Non object type", () => {
76-
it("should error", () =>
77-
{
78-
const introspected = introspect(expectionsEmptyTopic, introspectionWrongTypeOnTopic);
79-
expect(introspected);
80-
81-
});
77+
describe('Non object type', () => {
78+
it('should error', () => {
79+
const introspected = introspect(
80+
expectionsEmptyTopic,
81+
introspectionWrongTypeOnTopic
82+
);
83+
expect(introspected);
84+
});
8285
});
83-

client/Contexts/Introspect/Introspection.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ const indexBy = <T>(array: readonly T[], propName: string) => {
4949
return keyBy(array, (thing) => {
5050
const prop = thing[propName];
5151
if (typeof prop !== 'string') {
52-
throw new Error(
53-
`key identified by ${propName} must be of type string`
54-
);
52+
throw new Error(`key identified by ${propName} must be of type string`);
5553
}
5654
return prop;
5755
});

client/Contexts/Introspect/mock/expectations-basic.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ export default {
4646
},
4747
subscriptions: {
4848
topicsUpdate: ({ subscriptions }) => {
49-
return subscriptions['topicAdded'] &&
49+
return (
50+
subscriptions['topicAdded'] &&
5051
subscriptions['topicAdded'].type.kind === 'OBJECT' &&
51-
subscriptions['topicAdded'].type.name === 'Topic';
52+
subscriptions['topicAdded'].type.name === 'Topic'
53+
);
5254
}, // function that checks for a named subscription which relates to topics
5355
},
5456
},

client/Contexts/Introspect/mock/expectations-empty-topic.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ import { Expectations } from '../ExpectationTypes';
88
export default {
99
Topic: {
1010
type: 'Topic', // the GraphQL type name
11-
fields: {}
11+
fields: {},
1212
},
1313
} as Expectations;

client/Contexts/Introspect/mock/expectations-missing-mutation.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ export default {
1111
operations: {
1212
create: ({ mutations }) => {
1313
if (Object.keys(mutations).length === 0) {
14-
throw new Error("mutations is empty")
14+
throw new Error('mutations is empty');
1515
}
1616
return true;
1717
},
18-
}
18+
},
1919
},
2020
} as Expectations;

0 commit comments

Comments
 (0)