74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
|
import ApplicationComponent from "wms-core/ApplicationComponent";
|
||
|
import {Express, Router} from "express";
|
||
|
import ldap, {InsufficientAccessRightsError, InvalidCredentialsError, Server} from "ldapjs";
|
||
|
import Logger from "wms-core/Logger";
|
||
|
import Username from "./models/Username";
|
||
|
import UserEmail from "wms-core/auth/models/UserEmail";
|
||
|
import {PasswordAuthProof} from "./models/UserPassword";
|
||
|
import Throttler from "wms-core/Throttler";
|
||
|
|
||
|
export default class LDAPServerComponent extends ApplicationComponent<void> {
|
||
|
private server?: Server;
|
||
|
|
||
|
public async start(app: Express, router: Router): Promise<void> {
|
||
|
this.server = ldap.createServer({
|
||
|
log: console
|
||
|
});
|
||
|
let authorize = (req: any, res: any, next: any) => {
|
||
|
Logger.debug(req);
|
||
|
|
||
|
if (!req.connection.ldap.bindDN.equals('cn=root'))
|
||
|
return next(new InsufficientAccessRightsError());
|
||
|
|
||
|
return next();
|
||
|
};
|
||
|
this.server.bind('ou=users,dc=toot,dc=party', async (req: any, res: any, next: any) => {
|
||
|
const rdns = req.dn.toString().split(', ').map((rdn: string) => rdn.split('='));
|
||
|
let username;
|
||
|
let email;
|
||
|
for (const rdn of rdns) {
|
||
|
if (rdn[0] === 'cn') {
|
||
|
username = rdn[1];
|
||
|
} else if (rdn[0] === 'email') {
|
||
|
email = rdn[1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Logger.debug('Matrix authentication attempt:', username, email);
|
||
|
|
||
|
try {
|
||
|
Throttler.throttle('ldap_auth', 3, 30 * 1000, username);
|
||
|
} catch (e) {
|
||
|
Logger.debug('Too many auth requests');
|
||
|
next(new InvalidCredentialsError());
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const user = await Username.getUserFromUsername(username);
|
||
|
if (user) {
|
||
|
const email = await UserEmail.getMainFromUser(user.id!);
|
||
|
if (email) {
|
||
|
const authProof = new PasswordAuthProof(email.email!);
|
||
|
if (await authProof.authorize(req.credentials)) {
|
||
|
Logger.debug('Success');
|
||
|
res.end();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Logger.debug('Fail');
|
||
|
next(new InvalidCredentialsError());
|
||
|
});
|
||
|
this.server.unbind((req: any, res: any, next: any) => {
|
||
|
Logger.debug('Unbind', req);
|
||
|
next();
|
||
|
});
|
||
|
this.server.listen(8389, '127.0.0.1', () => {
|
||
|
Logger.info(`LDAP server listening on ${this.server!.url}`);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public async stop(): Promise<void> {
|
||
|
}
|
||
|
}
|