import { Database } from "../Database"; import { Helper, BotManager, Context, User } from "../Core"; import { Bot } from "../Bot"; const Rx = require("rx").Rx; const key = "roles"; class RoleManager { data: any; db: Database; bot: Bot; constructor(db: Database, bot: Bot) { this.db = db; this.bot = bot; if (!this.db.get(key)) this.db.set(key, {}); this.data = this.db.get(key); } create(name: string) { this.data[name] = []; this.saveChanges(); } delete(name: string) { if (!this.exists(name)) throw new Error("Role does not exist"); delete this.data[name]; this.saveChanges(); } get(name: string): User[] { var role = this.data[name]; var result: User[] = []; role.forEach(element => { result.push(this.bot.getUserById(element)); }); return result; } addUserToRole(role: string, userId: string) { if (!this.exists(role)) throw new Error("Role does not exist"); var r = this.data[role]; if (this.userInRole(role, userId)) throw new Error("User is already in role"); r.push(userId); this.saveChanges(); } removeUserFromRole(role: string, userId: string) { if (!this.exists(role)) throw new Error("Role does not exist"); var r = this.data[role]; if (!this.userInRole(role, userId)) throw new Error("User is not in role"); r.pop(userId); this.saveChanges(); } userInRole(role: string, userId: string): boolean { if (!this.exists(role)) throw new Error("Role does not exist"); return this.data[role].find(i => i == userId) != null; } saveChanges() { this.db.set(key, this.data); } exists(name: string): boolean { if (this.data[name]) return true; return false; } getRoles(): string[] { return Object.getOwnPropertyNames(this.data); } } Rx.Observable.prototype.requiresRole = function(role) { var source = this; return Rx.Observable.create(observer => { return source.subscribe( msg => { try { var u = msg.user; var r = Helper.getValue(msg, role); var roleManager = BotManager.get(msg.botId).roleManager; if (roleManager.userInRole(r, u.id)) { observer.onNext(msg); } else { BotManager.get(msg.botId).reply( "Sorry, you don't have the correct privileges to do that", msg ); } } catch (e) { observer.onError(e); } }, observer.onError.bind(observer), observer.onCompleted.bind(observer) ); }); }; var roleDoesNotExist = function(role) { return ( "Role `" + role + "` does not exist. Try `create role " + role + "` to create it first" ); }; export class Auth { static pluginName: string = "auth"; static description: string = "Authorization and Role Manager"; static apply(bot: Bot) { var roleManager = new RoleManager( new Database("auth", { roles: [ ] }), bot ); bot .hear("(create|add) role {name:string}") .assert( m => !roleManager.exists(m.name), m => `Role \`${m.name}\` already exists.` ) .do(m => roleManager.create(m.name)) .reply(m => `Role \`${m.name}\` has been created`) .start(); bot .hear("add {username:user} to {role}") // .or("give {username:user} {role}") // .or("give {role} to {username:user}") .assert(m => roleManager.exists(m.role), m => roleDoesNotExist(m.role)) .assert( m => !roleManager.userInRole(m.role, m.username.id), m => `${m.username.displayName} already has role \`${m.role}\`` ) .do(m => roleManager.addUserToRole(m.role, m.username.id)) .reply(m => `${m.username.displayName} has been added to ${m.role}`) .start(); bot .hear("(remove|rem|delete) {username:user} from {role}") .assert(m => roleManager.exists(m.role), m => roleDoesNotExist(m.role)) .assert( m => roleManager.userInRole(m.role, m.username.id), m => `${m.username.displayName} does not have the ${m.role} role` ) .do(m => roleManager.removeUserFromRole(m.role, m.username.id)) .reply( m => `${m.username.displayName} has been removed from \`${m.role}\`` ) .start(); bot .hear("get roles") .reply(m => { var roles = roleManager.getRoles(); if (roles.length > 0) return ( "There are " + Helper.numberString(roles.length) + " roles set up so far: `" + roles.join("`, `") + "` \n\n" + "*Hint*: type `get role {role}` to get a list of users with a given role" ); else return "There aren't any roles yet, use Use `create-role {name}` to create some"; }) .start(); bot .hear("get role {role}") .assert(m => roleManager.exists(m.role), m => roleDoesNotExist(m.role)) .reply(m => { var r = roleManager.get(m.role); var users = []; r.forEach(element => { users.push(element.displayName); }); if (users.length == 0) { return ( "You haven't added any users to this role yet \n\n*Hint:* try `add {username} to " + m.role + "`" ); } return ( "There are " + Helper.numberString(r.length) + " user(s) in role `" + m.role + "`: " + users.join(", ") ); }) .start(); bot .hear("(delete|remove|del|rem) role {role}") .assert(m => roleManager.exists(m.role), m => roleDoesNotExist(m.role)) .confirm(m => "Are you sure you want to *delete* role `" + m.role + "`?") .do(m => roleManager.delete(m.role)) .reply(m => `Role \`${m.role}\` deleted :thumbsup:`) .start(); } }