feat: added allowRegistration option

This commit is contained in:
Wyatt Johnson
2018-10-25 12:57:20 -06:00
parent d1e6d297f3
commit 3c613754f0
8 changed files with 121 additions and 57 deletions
@@ -136,13 +136,10 @@ export const OIDCIDTokenSchema = Joi.object()
email: Joi.string(),
email_verified: Joi.boolean().default(false),
picture: Joi.string().default(undefined),
name: Joi.string().default(undefined),
nickname: Joi.string().default(undefined),
})
.optionalKeys(["picture", "email_verified"]);
export const OIDCDisplayNameIDTokenSchema = OIDCIDTokenSchema.keys({
name: Joi.string().default(undefined),
nickname: Joi.string().default(undefined),
}).optionalKeys(["name", "nickname"]);
.optionalKeys(["picture", "email_verified", "name", "nickname"]);
export async function findOrCreateOIDCUser(
db: Db,
@@ -160,12 +157,7 @@ export async function findOrCreateOIDCUser(
picture,
name,
nickname,
}: OIDCIDToken = validate(
integration.displayNameEnable
? OIDCDisplayNameIDTokenSchema
: OIDCIDTokenSchema,
token
);
}: OIDCIDToken = validate(OIDCIDTokenSchema, token);
// Construct the profile that will be used to query for the user.
const profile: OIDCProfile = {
@@ -178,10 +170,13 @@ export async function findOrCreateOIDCUser(
// Try to lookup user given their id provided in the `sub` claim.
let user = await retrieveUserWithProfile(db, tenant.id, profile);
if (!user) {
if (!integration.allowRegistration) {
// Registration is disabled, so we can't create the user user here.
return;
}
// FIXME: implement rules.
// Default the displayName. When it is disabled, Joi will strip the
// displayName fields from the token, so it will fallback to undefined.
const displayName = nickname || name || undefined;
// Create the new user, as one didn't exist before!
@@ -1,7 +1,4 @@
import {
OIDCDisplayNameIDTokenSchema,
OIDCIDTokenSchema,
} from "talk-server/app/middleware/passport/strategies/oidc";
import { OIDCIDTokenSchema } from "talk-server/app/middleware/passport/strategies/oidc";
import { validate } from "talk-server/app/request/body";
describe("OIDCIDTokenSchema", () => {
@@ -42,9 +39,7 @@ describe("OIDCIDTokenSchema", () => {
expect(validate(OIDCIDTokenSchema, token)).toEqual(token);
});
});
describe("OIDCDisplayNameIDTokenSchema", () => {
it("allows a valid payload", () => {
const token = {
sub: "sub",
@@ -56,7 +51,7 @@ describe("OIDCDisplayNameIDTokenSchema", () => {
nickname: "nickname",
};
expect(validate(OIDCDisplayNameIDTokenSchema, token)).toEqual(token);
expect(validate(OIDCIDTokenSchema, token)).toEqual(token);
});
it("allows an empty name", () => {
@@ -69,7 +64,7 @@ describe("OIDCDisplayNameIDTokenSchema", () => {
nickname: "nickname",
};
expect(validate(OIDCDisplayNameIDTokenSchema, token)).toEqual(token);
expect(validate(OIDCIDTokenSchema, token)).toEqual(token);
});
it("allows an empty nickname", () => {
@@ -82,6 +77,6 @@ describe("OIDCDisplayNameIDTokenSchema", () => {
name: "name",
};
expect(validate(OIDCDisplayNameIDTokenSchema, token)).toEqual(token);
expect(validate(OIDCIDTokenSchema, token)).toEqual(token);
});
});
@@ -1,6 +1,5 @@
import {
isSSOToken,
SSODisplayNameUserProfileSchema,
SSOUserProfileSchema,
} from "talk-server/app/middleware/passport/strategies/verifiers/sso";
import { validate } from "talk-server/app/request/body";
@@ -44,9 +43,7 @@ describe("SSOUserProfileSchema", () => {
expect(validate(SSOUserProfileSchema, profile)).toEqual(profile);
});
});
describe("SSODisplayNameUserProfileSchema", () => {
it("allows a valid payload", () => {
const profile = {
id: "id",
@@ -56,7 +53,7 @@ describe("SSODisplayNameUserProfileSchema", () => {
displayName: "displayName",
};
expect(validate(SSODisplayNameUserProfileSchema, profile)).toEqual(profile);
expect(validate(SSOUserProfileSchema, profile)).toEqual(profile);
});
it("allows an empty avatar", () => {
@@ -67,7 +64,7 @@ describe("SSODisplayNameUserProfileSchema", () => {
displayName: "displayName",
};
expect(validate(SSODisplayNameUserProfileSchema, profile)).toEqual(profile);
expect(validate(SSOUserProfileSchema, profile)).toEqual(profile);
});
it("allows an empty displayName", () => {
@@ -78,6 +75,6 @@ describe("SSODisplayNameUserProfileSchema", () => {
avatar: "avatar",
};
expect(validate(SSODisplayNameUserProfileSchema, profile)).toEqual(profile);
expect(validate(SSOUserProfileSchema, profile)).toEqual(profile);
});
});
@@ -3,7 +3,10 @@ import jwt from "jsonwebtoken";
import { Db } from "mongodb";
import { validate } from "talk-server/app/request/body";
import { GQLUSER_ROLE } from "talk-server/graph/tenant/schema/__generated__/types";
import {
GQLSSOAuthIntegration,
GQLUSER_ROLE,
} from "talk-server/graph/tenant/schema/__generated__/types";
import { Tenant } from "talk-server/models/tenant";
import { retrieveUserWithProfile, SSOProfile } from "talk-server/models/user";
import { upsert } from "talk-server/services/users";
@@ -30,16 +33,14 @@ export const SSOUserProfileSchema = Joi.object()
email: Joi.string(),
username: Joi.string(),
avatar: Joi.string().default(undefined),
displayName: Joi.string().default(undefined),
})
.optionalKeys(["avatar"]);
export const SSODisplayNameUserProfileSchema = SSOUserProfileSchema.keys({
displayName: Joi.string().default(undefined),
}).optionalKeys(["displayName"]);
.optionalKeys(["avatar", "displayName"]);
export async function findOrCreateSSOUser(
db: Db,
tenant: Tenant,
integration: GQLSSOAuthIntegration,
token: SSOToken
) {
if (!token.user) {
@@ -49,9 +50,7 @@ export async function findOrCreateSSOUser(
// Unpack/validate the token content.
const { id, email, username, displayName, avatar }: SSOUserProfile = validate(
tenant.auth.integrations.sso!.displayNameEnable
? SSODisplayNameUserProfileSchema
: SSOUserProfileSchema,
SSOUserProfileSchema,
token.user
);
@@ -63,6 +62,11 @@ export async function findOrCreateSSOUser(
// Try to lookup user given their id provided in the `sub` claim.
let user = await retrieveUserWithProfile(db, tenant.id, profile);
if (!user) {
if (!integration.allowRegistration) {
// Registration is disabled, so we can't create the user user here.
return;
}
// FIXME: (wyattjoh) implement rules! Not all users should be able to create an account via this method.
// Create the new user, as one didn't exist before!
@@ -138,6 +142,6 @@ export class SSOVerifier {
algorithms: ["HS256"], // TODO: (wyattjoh) investigate replacing algorithm.
});
return findOrCreateSSOUser(this.mongo, tenant, token);
return findOrCreateSSOUser(this.mongo, tenant, integration, token);
}
}