-
Notifications
You must be signed in to change notification settings - Fork 409
Implements Auth provider configuration management APIs #415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…g SAML and OIDC providers. ``` listProviderConfigs( options: admin.auth.AuthProviderConfigFilter ): Promise<admin.auth.ListProviderConfigResults>; getProviderConfig(providerId: string): Promise<admin.auth.AuthProviderConfig> deleteProviderConfig(providerId: string): Promise<void>; updateProviderConfig( providerId: string, updatedConfig: admin.auth.UpdateAuthProviderRequest ): Promise<admin.auth.AuthProviderConfig>; createProviderConfig( config: admin.auth.AuthProviderConfig ): Promise<admin.auth.AuthProviderConfig>; ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't gone into the unit tests yet. But I've pointed out a bunch of potential changes in the rest of the code. Looks mostly good. Lets try to reduce the use of any
wherever possible.
src/auth/auth-api-request.ts
Outdated
request.pageSize > MAX_LIST_PROVIDER_CONFIGURATION_PAGE_SIZE) { | ||
throw new FirebaseAuthError( | ||
AuthClientErrorCode.INVALID_ARGUMENT, | ||
`Required "maxResults" must be a positive non-zero number that does not exceed ` + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be "positive integer that does not...". Positive implies non-zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/auth/auth-api-request.ts
Outdated
constructor(app: FirebaseApp) { | ||
this.httpClient = new AuthorizedHttpClient(app); | ||
this.authUrlBuilder = new AuthResourceUrlBuilder(utils.getProjectId(app), 'v1'); | ||
this.projectConfigUrlBuilder = new AuthResourceUrlBuilder(utils.getProjectId(app), 'v2beta1'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Refactor getProjectId(app)
into a constant.
const projectId = utils.getProjectId(app);
this.authUrlBuilder = ...
this.projectConfigUrlBuilder = ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/auth-api-request.ts
Outdated
* | ||
* @param {number=} maxResults The page size, 100 if undefined. This is also the maximum | ||
* allowed limit. | ||
* @param {string=} pageToken The next page token. If not specified, returns OIDC configurations starting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove "starting"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/auth-api-request.ts
Outdated
* @param {string} providerId The provider identifier of the configuration to lookup. | ||
* @return {Promise<object>} A promise that resolves with the provider configuration information. | ||
*/ | ||
public getOAuthIdpConfig(providerId: string): Promise<object> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be declared to return a more specific type than object
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. I've gone through both impl and tests, and made several comments.
I also think we probably should have done this in 2 PRs (one for OIDC and one for SAML). Lets work on making smaller PRs in the future.
src/auth/auth.ts
Outdated
* meeting the filter requirements. | ||
*/ | ||
public listProviderConfigs(options: AuthProviderConfigFilter): Promise<ListProviderConfigResults> { | ||
const processResponse = (response: any, providerConfigs: AuthProviderConfig[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declare return type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/utils/index.ts
Outdated
for (const key in obj) { | ||
if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') { | ||
let maskList: string[] = []; | ||
maskList = generateUpdateMask(obj[key]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const maskList = generateUpdateMask(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/auth-api-request.ts
Outdated
export class FirebaseAuthRequestHandler { | ||
private httpClient: AuthorizedHttpClient; | ||
private authUrlBuilder: AuthResourceUrlBuilder; | ||
private projectConfigUrlBuilder: AuthResourceUrlBuilder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these can be readonly
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/auth/auth-api-request.ts
Outdated
pageToken, | ||
}; | ||
// Remove next page token if not provided. | ||
if (typeof request.pageToken === 'undefined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can work around this by putting an explicit any
on request. Or even:
const request: {pageSize: number, pageToken?: string} = ...;
is not too much of a hassle. But I'm ok if you choose to leave this as is for this PR.
test/unit/auth/auth.spec.ts
Outdated
// Stub listOAuthIdpConfigs to return expected response. | ||
const listConfigsStub = sinon | ||
.stub(FirebaseAuthRequestHandler.prototype, 'listOAuthIdpConfigs') | ||
.returns(Promise.resolve(listConfigsResponse)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.resolves(listConfigsResponse)
. Here and elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
// Stub listOAuthIdpConfigs to throw a backend error. | ||
const listConfigsStub = sinon | ||
.stub(FirebaseAuthRequestHandler.prototype, 'listOAuthIdpConfigs') | ||
.returns(Promise.reject(expectedError)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.rejects(expectedError)
. Here and elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
throw new Error('Unexpected success'); | ||
}) | ||
.catch((error) => { | ||
expect(error).to.have.property('code', 'auth/argument-error'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we do .should.eventually.be.rejected.and.have.property
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
providerConfigs: [], | ||
}; | ||
|
||
it('should resolve on listInboundSamlConfigs request success with configs in response', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should resolve on success with configs in response
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
describe('getOAuthIdpConfig()', () => { | ||
const providerId = 'oidc.provider'; | ||
const path = `/v2beta1/projects/project_id/oauthIdpConfigs/${providerId}`; | ||
const method = 'GET'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Calling this getMethod
or httpGet
would make the rest of the code more readable. Or even using the string literal as callParams(path, 'GET', {})
is not a bad idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to expectedHttpMethod
here and all the new proposed APIs We need to assert this value in all the suite test. It is better not to hardcode it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Appreciate the review.
Regarding the PR being too long, as mentioned in another comment, the way we have been doing things, it is unlikely we can split into multiple PRs since partial features would be available in master before launchcals are approved.
What I can do going forward is split into smaller commits and request reviews one part at a time.
src/auth/auth.ts
Outdated
* meeting the filter requirements. | ||
*/ | ||
public listProviderConfigs(options: AuthProviderConfigFilter): Promise<ListProviderConfigResults> { | ||
const processResponse = (response: any, providerConfigs: AuthProviderConfig[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/auth/auth-api-request.ts
Outdated
throw new FirebaseAuthError( | ||
AuthClientErrorCode.INVALID_ARGUMENT, | ||
`Required "maxResults" must be a positive integer that does not exceed ` + | ||
`the allowed ${MAX_LIST_PROVIDER_CONFIGURATION_PAGE_SIZE}.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/auth/auth-api-request.ts
Outdated
export class FirebaseAuthRequestHandler { | ||
private httpClient: AuthorizedHttpClient; | ||
private authUrlBuilder: AuthResourceUrlBuilder; | ||
private projectConfigUrlBuilder: AuthResourceUrlBuilder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
test/unit/auth/auth.spec.ts
Outdated
throw new Error('Unexpected success'); | ||
}) | ||
.catch((error) => { | ||
expect(error).to.have.property('code', 'auth/argument-error'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
providerConfigs: [], | ||
}; | ||
|
||
it('should resolve on listOAuthIdpConfigs request success with configs in response', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
// Stub listOAuthIdpConfigs to return expected response. | ||
const listConfigsStub = sinon | ||
.stub(FirebaseAuthRequestHandler.prototype, 'listOAuthIdpConfigs') | ||
.returns(Promise.resolve(listConfigsResponse)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
// Stub listOAuthIdpConfigs to throw a backend error. | ||
const listConfigsStub = sinon | ||
.stub(FirebaseAuthRequestHandler.prototype, 'listOAuthIdpConfigs') | ||
.returns(Promise.reject(expectedError)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/unit/auth/auth.spec.ts
Outdated
providerConfigs: [], | ||
}; | ||
|
||
it('should resolve on listInboundSamlConfigs request success with configs in response', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes. LGTM 👍
As for managing large changes, this is what I would recommend.
|
Implements Auth provider configuration management APIs for configuring SAML and OIDC providers.