Skip to content

Commit 088e521

Browse files
Merge pull request #8325 from sagemathinc/sso-dot-object-delimiter
sso/auth: customize separator for dot-object
2 parents 97d2259 + e879895 commit 088e521

File tree

6 files changed

+55
-49
lines changed

6 files changed

+55
-49
lines changed

src/packages/database/settings/auth-sso-types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ export type PassportLoginInfo = { [key in LoginInfoKeys]?: string };
8080
* The remaining fields, except for type, clientID, clientSecret, and callbackURL, userinfoURL, login_info are passed to that constructor.
8181
* Additionally, there are default values for some of the fields, e.g. for the SAML2.0 strategy.
8282
* Please check the hub/auth.ts file for more details.
83+
*
8384
* Regarding the userinfoURL, this is used by OAuth2 to get the profile.
85+
*
8486
* The "login_info" field is a mapping from "cocalc" profile fields, that end up in the DB,
8587
* to the entries in the generated profile object. The DB entry can only be a string and
8688
* processing is done by using the "dot-object" npm library.
@@ -91,6 +93,7 @@ export type PassportLoginInfo = { [key in LoginInfoKeys]?: string };
9193
* last_name: "name.familyName",
9294
* emails: "emails[0].value",
9395
* }
96+
* You can to customize the separator of dot-object, e.g. to process keys with dots, add a "_sep: string" entry.
9497
*/
9598
export interface PassportStrategyDBConfig {
9699
type: PassportTypes;

src/packages/pnpm-lock.yaml

Lines changed: 6 additions & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/packages/server/hub/auth.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// just a sanity check for dot-object
2+
3+
import dot from "dot-object";
4+
5+
describe("dot-object", () => {
6+
const o = {
7+
a: {
8+
b: "foo",
9+
"cd.1.2": "bar",
10+
},
11+
};
12+
13+
it("default delimiter", () => {
14+
const v = dot.pick("a.b", o);
15+
expect(v).toEqual("foo");
16+
});
17+
18+
it("custom delimiter", () => {
19+
const d = new dot("->");
20+
const v = d.pick("a->cd.1.2", o);
21+
expect(v).toEqual("bar");
22+
});
23+
});

src/packages/server/hub/auth.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,17 @@
3434
// Then restart the hubs.
3535

3636
import Cookies from "cookies";
37-
import * as dot from "dot-object";
37+
import dot from "dot-object";
3838
import type { NextFunction, Request, Response } from "express";
3939
import * as express from "express";
4040
import express_session from "express-session";
4141
import * as _ from "lodash";
4242
import ms from "ms";
4343
import passport, { AuthenticateOptions } from "passport";
4444
import { join as path_join } from "path";
45-
import { v4 as uuidv4, v4 } from "uuid";
4645
import safeJsonStringify from "safe-json-stringify";
46+
import { v4 as uuidv4, v4 } from "uuid";
47+
4748
import passwordHash, {
4849
verifyPassword,
4950
} from "@cocalc/backend/auth/password-hash";
@@ -79,6 +80,7 @@ import {
7980
getOauthCache,
8081
getPassportCache,
8182
} from "@cocalc/database/postgres/passport-store";
83+
import { getServerSettings } from "@cocalc/database/settings";
8284
import {
8385
PassportLoginOpts,
8486
PassportStrategyDB,
@@ -87,6 +89,7 @@ import {
8789
isOAuth2,
8890
isSAML,
8991
} from "@cocalc/database/settings/auth-sso-types";
92+
import { signInUsingImpersonateToken } from "@cocalc/server/auth/impersonate";
9093
import {
9194
BLACKLISTED_STRATEGIES,
9295
DEFAULT_LOGIN_INFO,
@@ -98,8 +101,6 @@ import {
98101
GoogleStrategyConf,
99102
TwitterStrategyConf,
100103
} from "@cocalc/server/auth/sso/public-strategies";
101-
import { getServerSettings } from "@cocalc/database/settings";
102-
import { signInUsingImpersonateToken } from "@cocalc/server/auth/impersonate";
103104

104105
const logger = getLogger("server:hub:auth");
105106

@@ -143,7 +144,7 @@ interface HandleReturnOpts {
143144
type: PassportTypes;
144145
update_on_login: boolean;
145146
cookie_ttl_s: number | undefined;
146-
login_info: any;
147+
login_info;
147148
}
148149

149150
export class PassportManager {
@@ -655,14 +656,16 @@ export class PassportManager {
655656
site_url: this.site_url,
656657
};
657658

659+
const dotInstance = this.getDot(login_info);
660+
658661
for (const k in login_info) {
659662
const v = login_info[k];
660663
const param: string | string[] =
661664
typeof v == "function"
662665
? // v is a LoginInfoDerivator<T>
663666
v(profile)
664667
: // v is a string for dot-object
665-
dot.pick(v, profile);
668+
dotInstance.pick(v, profile);
666669
login_opts[k] = param;
667670
}
668671

@@ -687,6 +690,18 @@ export class PassportManager {
687690
};
688691
}
689692

693+
private getDot(login_info): DotObject.Dot {
694+
// if login_info contains a key "_delimiter", take it from that object and remove it
695+
// then instantiate dot with that delimiter and use it to pick the values
696+
if (typeof login_info._sep === "string") {
697+
const sep = login_info._sep;
698+
delete login_info._sep;
699+
return new dot(sep);
700+
} else {
701+
return dot;
702+
}
703+
}
704+
690705
// right now, we only set this for OAauth2 (SAML knows what to do on its own)
691706
// This does not encode any information for now.
692707
private setState(

src/packages/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"cloudflare": "^2.9.1",
8787
"cookies": "^0.8.0",
8888
"dayjs": "^1.11.11",
89-
"dot-object": "^2.1.4",
89+
"dot-object": "^2.1.5",
9090
"express-session": "^1.18.1",
9191
"google-auth-library": "^9.4.1",
9292
"googleapis": "^137.1.0",

src/scripts/auth/gen-sso.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
"full_name": "displayName",
161161
"emails": "email",
162162
"id": "email",
163+
# "_sep": "->", # uncomment this to test _sep, no need to change the values above
163164
},
164165
"issuer": "https://cocalc.com",
165166
"cert": saml20cert

0 commit comments

Comments
 (0)