更换socket鉴权方式

pull/10/head
undefined 4 years ago
parent 8bb389eedd
commit b9076cd5d3

@ -62,10 +62,7 @@ class DiscussionHandler extends Handler {
// TODO(twd2): exclude problem/contest discussions?
// TODO(iceboy): continuation based pagination.
if (ObjectID.isValid(name)) name = new ObjectID(name);
this.vnode = await discussion.getVnode(domainId, {
parentType: typeMapper[type],
parentId: name,
}, this);
this.vnode = await discussion.getVnode(domainId, typeMapper[type], name, this);
if (this.ddoc) {
this.ddoc.parentType = this.ddoc.parentType || this.vnode.type;
this.ddoc.parentId = this.ddoc.parentId || this.vnode.id;

@ -102,12 +102,6 @@ class SwitchLanguageHandler extends Handler {
}
}
class SockToken extends Handler {
async get() {
this.response.body = { token: this.UIContext.token };
}
}
class UiSettingsHandler extends Handler {
async get() {
const [
@ -143,7 +137,6 @@ export async function apply() {
Route('status', '/status', StatusHandler);
Route('status_update', '/status/update', StatusUpdateHandler);
Route('switch_language', '/language/:lang', SwitchLanguageHandler);
Route('token', '/token', SockToken);
Route('ui', '/extra.css', UiSettingsHandler);
}

@ -158,33 +158,33 @@ export function getNode(domainId: string, _id: string) {
return document.get(domainId, document.TYPE_DISCUSSION_NODE, _id);
}
export async function getVnode(domainId: string, ddoc: any, handler: any) {
if (ddoc.parentType === document.TYPE_PROBLEM) {
const pdoc = await problem.get(domainId, ddoc.parentId);
export async function getVnode(domainId: string, type: number, id: string, handler: any) {
if (type === document.TYPE_PROBLEM) {
const pdoc = await problem.get(domainId, id);
if (!pdoc) return null;
if (pdoc.hidden && handler) handler.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN);
return { ...pdoc, type: ddoc.parentType, id: ddoc.parentId };
return { ...pdoc, type, id };
}
if (ddoc.parentType === document.TYPE_CONTEST) {
const tdoc = await contest.get(domainId, ddoc.parentId);
return { ...tdoc, type: ddoc.parentType, id: ddoc.parentId };
if (type === document.TYPE_CONTEST) {
const tdoc = await contest.get(domainId, new ObjectID(id));
return { ...tdoc, type, id };
}
if (ddoc.parentType === document.TYPE_DISCUSSION_NODE) {
const ndoc = await getNode(domainId, ddoc.parentId);
if (type === document.TYPE_DISCUSSION_NODE) {
const ndoc = await getNode(domainId, id);
return {
...ndoc,
title: ddoc.parentId,
type: ddoc.parentType,
id: ddoc.parentId,
title: id,
type,
id,
};
}
if (ddoc.parentType === document.TYPE_TRAINING) {
const tdoc = await training.get(domainId, ddoc.parentId);
return { ...tdoc, type: ddoc.parentType, id: ddoc.parentId };
if (type === document.TYPE_TRAINING) {
const tdoc = await training.get(domainId, id);
return { ...tdoc, type, id };
}
if (ddoc.parentType === document.TYPE_HOMEWORK) {
const tdoc = await contest.get(domainId, ddoc.parentId, document.TYPE_HOMEWORK);
return { ...tdoc, type: ddoc.parentType, id: ddoc.parentId };
if (type === document.TYPE_HOMEWORK) {
const tdoc = await contest.get(domainId, new ObjectID(id), document.TYPE_HOMEWORK);
return { ...tdoc, type, id };
}
return {
title: 'Missing Node',
@ -201,7 +201,7 @@ export async function getListVnodes(domainId: string, ddocs: any, handler: any)
const tasks = [];
const res = {};
async function task(ddoc) {
const vnode = await getVnode(domainId, ddoc, handler);
const vnode = await getVnode(domainId, ddoc.parentType, ddoc.parentId, handler);
if (!res[ddoc.parentType]) res[ddoc.parentType] = {};
res[ddoc.parentType][ddoc.parentId] = vnode;
}

@ -4,7 +4,6 @@ import * as db from '../service/db';
const coll = db.collection('token');
export const TYPE_SESSION = 0;
export const TYPE_TOKEN = 1;
export const TYPE_REGISTRATION = 2;
export const TYPE_CHANGEMAIL = 3;
export const TYPE_OAUTH = 4;
@ -90,7 +89,6 @@ global.Hydro.postInit.push(ensureIndexes);
global.Hydro.model.token = {
TYPE_SESSION,
TYPE_CHANGEMAIL,
TYPE_TOKEN,
TYPE_OAUTH,
TYPE_REGISTRATION,
TYPE_LOSTPASS,

@ -12,6 +12,7 @@ import Body from 'koa-body';
import Router from 'koa-router';
import cache from 'koa-static-cache';
import sockjs from 'sockjs';
import { SetOption } from 'cookies';
import serialize, { SerializeJSOptions } from 'serialize-javascript';
import { argv } from 'yargs';
import { lrucache } from '../utils';
@ -365,28 +366,14 @@ export class Handler {
]);
if (!this.domain) {
this.args.domainId = 'system';
[this.user, this.UIContext.token] = await Promise.all([
user.getById('system', this.session.uid),
token.createOrUpdate(
token.TYPE_TOKEN, 600, { uid: this.session.uid, domainId },
),
]);
this.user = await user.getById('system', this.session.uid);
if (!this.user) this.user = await user.getById('system', 0);
throw new NotFoundError(domainId);
}
[this.user, this.UIContext.token] = await Promise.all([
user.getById(domainId, this.session.uid),
token.createOrUpdate(
token.TYPE_TOKEN, 600, { uid: this.session.uid, domainId },
),
]);
this.user = await user.getById(domainId, this.session.uid);
if (!this.user) {
this.session.uid = 0;
[this.user, this.UIContext.token] = await Promise.all([
user.getById(domainId, this.session.uid),
token.createOrUpdate(
token.TYPE_TOKEN, 600, { uid: this.session.uid, domainId },
),
]);
this.user = await user.getById(domainId, this.session.uid);
}
this.csrfToken = this.getCsrfToken(this.session._id || String.random(32));
this.UIContext.csrfToken = this.csrfToken;
@ -484,7 +471,10 @@ export class Handler {
},
);
}
const cookie: any = { secure: await system.get('session.secure') };
const cookie: SetOption = {
secure: await system.get('session.secure'),
httpOnly: false,
};
if (this.session.save) {
cookie.expires = this.session.expireAt;
cookie.maxAge = expireSeconds;
@ -492,7 +482,7 @@ export class Handler {
this.ctx.cookies.set('sid', this.session._id, cookie);
}
async onerror(error) {
async onerror(error: HydroError) {
if (!error.msg) error.msg = () => error.message;
console.error(error.msg(), error.params);
console.error(error.stack);
@ -600,6 +590,8 @@ export class ConnectionHandler {
user: any
domain: DomainDoc
constructor(conn: sockjs.Connection) {
this.conn = conn;
this.request = {
@ -683,10 +675,24 @@ export class ConnectionHandler {
this.close(1001, err.toString());
}
async init({ domainId }) {
this.session = await token.get(this.request.params.token, token.TYPE_TOKEN);
this.session = this.session || { uid: 0, domainId: 'system' };
this.args.domainId = this.session.domainId;
async getSession(cookieHeader: string) {
const cookies: any = {};
const ref = cookieHeader.split(';');
for (let j = 0; j < ref.length; j++) {
const cookie = ref[j];
const parts = cookie.split('=');
cookies[parts[0].trim()] = (parts[1] || '').trim();
}
this.session = await token.get(cookies.sid || '', token.TYPE_SESSION);
if (!this.session) this.session = { uid: 0, domainId: 'system' };
}
@param('cookie', Types.String)
async init(domainId: string, cookie: string) {
[this.domain] = await Promise.all([
domain.get(domainId),
this.getSession(cookie),
]);
const bdoc = await blacklist.get(this.request.ip);
if (bdoc) throw new BlacklistedError(this.request.ip);
this.user = await user.getById(domainId, this.session.uid);
@ -699,14 +705,21 @@ export function Connection(
RouteConnHandler: any,
...permPrivChecker: Array<number | bigint | Function>
) {
const sock = sockjs.createServer({ prefix });
const sock = sockjs.createServer({ prefix, log: (a, b) => console.log(a, b) });
const checker = Checker(permPrivChecker);
sock.on('connection', async (conn) => {
const h: Dictionary<any> = new RouteConnHandler(conn);
try {
const args = { domainId: 'system', ...h.request.params };
h.args = args;
const cookie = await new Promise((resolve) => {
conn.once('data', (c) => {
resolve(c);
});
});
args.cookie = cookie;
await h.init(args);
conn.write(JSON.stringify({ event: 'auth' }));
checker.call(h);
if (h._prepare) await h._prepare(args);

@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.11.2",
"version": "2.11.3",
"main": "dist/loader.js",
"bin": "bin/hydrooj.js",
"repository": "https://github.com/hydro-dev/Hydro.git",
@ -12,6 +12,7 @@
"dependencies": {
"adm-zip": "^0.4.16",
"ansi_up": "^4.0.4",
"cookies": "^0.8.0",
"detect-browser": "^5.1.1",
"fs-extra": "^9.0.1",
"html-to-text": "^5.1.1",

@ -759,7 +759,7 @@ cookiejar@^2.1.2:
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
cookies@~0.8.0:
cookies@^0.8.0, cookies@~0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90"
integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==

Loading…
Cancel
Save