WIP: Part deux

This commit is contained in:
David Teller 2022-07-27 12:48:27 +02:00
parent 829e1bd0aa
commit 570845a7ec
8 changed files with 51 additions and 51 deletions

View File

@ -27,7 +27,7 @@ import {
TextualMessageEventContent
} from "matrix-bot-sdk";
import { ALL_RULE_TYPES as ALL_BAN_LIST_RULE_TYPES, RULE_ROOM, RULE_SERVER, RULE_USER } from "./models/ListRule";
import { ALL_RULE_TYPES as ALL_BAN_LIST_RULE_TYPES, RULE_ROOM, RULE_SERVER, RULE_USER } from "./models/PolicyRule";
import { applyServerAcls } from "./actions/ApplyAcl";
import { RoomUpdateError } from "./models/RoomUpdateError";
import { COMMAND_PREFIX, handleCommand } from "./commands/CommandHandler";
@ -50,7 +50,7 @@ import RuleServer from "./models/RuleServer";
import { RoomMemberManager } from "./RoomMembers";
import { ProtectedRoomActivityTracker } from "./queues/ProtectedRoomActivityTracker";
import { ThrottlingQueue } from "./queues/ThrottlingQueue";
import PolicyList, { ListRuleChange } from "./models/PolicyList";
import PolicyList, { PolicyRuleChange } from "./models/PolicyList";
const levelToFn = {
[LogLevel.DEBUG.toString()]: LogService.debug,
@ -1052,7 +1052,7 @@ export class Mjolnir {
* @param ignoreSelf Whether to exclude changes that have been made by Mjolnir.
* @returns true if the message was sent, false if it wasn't (because there there were no changes to report).
*/
private async printBanlistChanges(changes: ListRuleChange[], list: PolicyList, ignoreSelf = false): Promise<boolean> {
private async printBanlistChanges(changes: PolicyRuleChange[], list: PolicyList, ignoreSelf = false): Promise<boolean> {
if (ignoreSelf) {
const sender = await this.client.getUserId();
changes = changes.filter(change => change.sender !== sender);

View File

@ -16,7 +16,7 @@ limitations under the License.
import { RichReply } from "matrix-bot-sdk";
import { Mjolnir } from "../Mjolnir";
import { EntityType } from "../models/ListRule";
import { EntityType } from "../models/PolicyRule";
import { htmlEscape } from "../utils";
/**

View File

@ -16,7 +16,7 @@ limitations under the License.
import { Mjolnir } from "../Mjolnir";
import { RichReply } from "matrix-bot-sdk";
import { EntityType, Recommendation } from "../models/ListRule";
import { EntityType, Recommendation } from "../models/PolicyRule";
// !mjolnir import <room ID> <shortcode>
export async function execImportCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {

View File

@ -17,7 +17,7 @@ limitations under the License.
import { Mjolnir } from "../Mjolnir";
import PolicyList from "../models/PolicyList";
import { extractRequestError, LogLevel, LogService, MatrixGlob, RichReply } from "matrix-bot-sdk";
import { Recommendation, RULE_ROOM, RULE_SERVER, RULE_USER, USER_RULE_TYPES } from "../models/ListRule";
import { Recommendation, RULE_ROOM, RULE_SERVER, RULE_USER, USER_RULE_TYPES } from "../models/PolicyRule";
import config from "../config";
import { DEFAULT_LIST_EVENT_TYPE } from "./SetDefaultBanListCommand";

View File

@ -16,7 +16,7 @@ limitations under the License.
import { extractRequestError, LogService, MatrixClient, UserID } from "matrix-bot-sdk";
import { EventEmitter } from "events";
import { ALL_RULE_TYPES, EntityType, ListRule, Recommendation, ROOM_RULE_TYPES, RULE_ROOM, RULE_SERVER, RULE_USER, SERVER_RULE_TYPES, USER_RULE_TYPES } from "./ListRule";
import { ALL_RULE_TYPES, EntityType, PolicyRule, Recommendation, ROOM_RULE_TYPES, RULE_ROOM, RULE_SERVER, RULE_USER, SERVER_RULE_TYPES, USER_RULE_TYPES } from "./PolicyRule";
export const SHORTCODE_EVENT_TYPE = "org.matrix.mjolnir.shortcode";
@ -26,7 +26,7 @@ export enum ChangeType {
Modified = "MODIFIED"
}
export interface ListRuleChange {
export interface PolicyRuleChange {
readonly changeType: ChangeType,
/**
* State event that caused the change.
@ -43,7 +43,7 @@ export interface ListRuleChange {
* The current rule represented by the event.
* If the rule has been removed, then this will show what the rule was.
*/
readonly rule: ListRule,
readonly rule: PolicyRule,
/**
* The previous state that has been changed. Only (and always) provided when the change type is `ChangeType.Removed` or `Modified`.
* This will be a copy of the same event as `event` when a redaction has occurred and this will show its unredacted state.
@ -53,8 +53,8 @@ export interface ListRuleChange {
declare interface PolicyList {
// PolicyList.update is emitted when the PolicyList has pulled new rules from Matrix and informs listeners of any changes.
on(event: 'PolicyList.update', listener: (list: PolicyList, changes: ListRuleChange[]) => void): this
emit(event: 'PolicyList.update', list: PolicyList, changes: ListRuleChange[]): boolean
on(event: 'PolicyList.update', listener: (list: PolicyList, changes: PolicyRuleChange[]) => void): this
emit(event: 'PolicyList.update', list: PolicyList, changes: PolicyRuleChange[]): boolean
// PolicyList.batch is emitted when the PolicyList has created a batch from the events provided by `updateForEvent`.
on(event: 'PolicyList.batch', listener: (list: PolicyList) => void): this
emit(event: 'PolicyList.batch', list: PolicyList): boolean
@ -118,10 +118,10 @@ class PolicyList extends EventEmitter {
/**
* Return all the active rules of a given kind.
* @param kind e.g. RULE_SERVER (m.policy.rule.server). Rule types are always normalised when they are interned into the PolicyList.
* @returns The active ListRules for the ban list of that kind.
* @returns The active PolicyRules for the ban list of that kind.
*/
private rulesOfKind(kind: string): ListRule[] {
const rules: ListRule[] = []
private rulesOfKind(kind: string): PolicyRule[] {
const rules: PolicyRule[] = []
const stateKeyMap = this.state.get(kind);
if (stateKeyMap) {
for (const event of stateKeyMap.values()) {
@ -146,19 +146,19 @@ class PolicyList extends EventEmitter {
});
}
public get serverRules(): ListRule[] {
public get serverRules(): PolicyRule[] {
return this.rulesOfKind(RULE_SERVER);
}
public get userRules(): ListRule[] {
public get userRules(): PolicyRule[] {
return this.rulesOfKind(RULE_USER);
}
public get roomRules(): ListRule[] {
public get roomRules(): PolicyRule[] {
return this.rulesOfKind(RULE_ROOM);
}
public get allRules(): ListRule[] {
public get allRules(): PolicyRule[] {
return [...this.serverRules, ...this.userRules, ...this.roomRules];
}
@ -169,7 +169,7 @@ class PolicyList extends EventEmitter {
* @param entity The entity to test e.g. the user id, server name or a room id.
* @returns All of the rules that match this entity.
*/
public rulesMatchingEntity(entity: string, ruleKind?: string): ListRule[] {
public rulesMatchingEntity(entity: string, ruleKind?: string): PolicyRule[] {
const ruleTypeOf: (entityPart: string) => string = (entityPart: string) => {
if (ruleKind) {
return ruleKind;
@ -233,8 +233,8 @@ class PolicyList extends EventEmitter {
* and updating the model to reflect the room.
* @returns A description of any rules that were added, modified or removed from the list as a result of this update.
*/
public async updateList(): Promise<ListRuleChange[]> {
let changes: ListRuleChange[] = [];
public async updateList(): Promise<PolicyRuleChange[]> {
let changes: PolicyRuleChange[] = [];
const state = await this.client.getRoomState(this.roomId);
for (const event of state) {
@ -313,11 +313,11 @@ class PolicyList extends EventEmitter {
changeType, event, sender, rule: previousState.unsigned.rule,
...previousState ? { previousState } : {}
});
// Event has no content and cannot be parsed as a ListRule.
// Event has no content and cannot be parsed as a PolicyRule.
continue;
}
// It's a rule - parse it
const rule = ListRule.parse(event);
const rule = PolicyRule.parse(event);
if (!rule) {
// Invalid/unknown rule, just skip it.
continue;

View File

@ -51,9 +51,9 @@ export enum Recommendation {
/// The rule specifies an "opinion", as a number in [-100, +100],
/// where -100 represents a user who is considered absolutely toxic
/// by whoever issued this ListRule and +100 represents a user who
/// by whoever issued this PolicyRule and +100 represents a user who
/// is considered absolutely absolutely perfect by whoever issued
/// this ListRule.
/// this PolicyRule.
Opinion = "org.matrix.msc3845.opinion",
}
@ -81,7 +81,7 @@ export const OPINION_MAX = +100;
/**
* Representation of a rule within a Policy List.
*/
export abstract class ListRule {
export abstract class PolicyRule {
/**
* A glob for `entity`.
*/
@ -115,12 +115,12 @@ export abstract class ListRule {
}
/**
* Validate and parse an event into a ListRule.
* Validate and parse an event into a PolicyRule.
*
* @param event An *untrusted* event.
* @returns null if the ListRule is invalid or not recognized by Mjölnir.
* @returns null if the PolicyRule is invalid or not recognized by Mjölnir.
*/
public static parse(event: {type: string, content: any}): ListRule | null {
public static parse(event: {type: string, content: any}): PolicyRule | null {
// Parse common fields.
// If a field is ill-formed, discard the rule.
const content = event['content'];
@ -155,17 +155,17 @@ export abstract class ListRule {
// From this point, we may need specific fields.
if (RECOMMENDATION_BAN_VARIANTS.includes(recommendation)) {
return new ListRuleBan(entity, reason, kind);
return new PolicyRuleBan(entity, reason, kind);
} else if (RECOMMENDATION_OPINION_VARIANTS.includes(recommendation)) {
let opinion = content['opinion'];
if (!Number.isInteger(opinion)) {
return null;
}
return new ListRuleOpinion(entity, reason, kind, opinion);
return new PolicyRuleOpinion(entity, reason, kind, opinion);
} else {
// As long as the `recommendation` is defined, we assume
// that the rule is correct, just unknown.
return new ListRuleUnknown(entity, reason, kind, content);
return new PolicyRuleUnknown(entity, reason, kind, content);
}
}
}
@ -173,7 +173,7 @@ export abstract class ListRule {
/**
* A rule representing a "ban".
*/
export class ListRuleBan extends ListRule {
export class PolicyRuleBan extends PolicyRule {
constructor(
/**
* The entity covered by this rule, e.g. a glob user ID, a room ID, a server domain.
@ -195,7 +195,7 @@ export class ListRuleBan extends ListRule {
/**
* A rule representing an "opinion"
*/
export class ListRuleOpinion extends ListRule {
export class PolicyRuleOpinion extends PolicyRule {
constructor(
/**
* The entity covered by this rule, e.g. a glob user ID, a room ID, a server domain.
@ -229,7 +229,7 @@ export class ListRuleOpinion extends ListRule {
/**
* Any list rule that we do not understand.
*/
export class ListRuleUnknown extends ListRule {
export class PolicyRuleUnknown extends PolicyRule {
constructor(
/**
* The entity covered by this rule, e.g. a glob user ID, a room ID, a server domain.

View File

@ -13,10 +13,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import BanList, { ChangeType, ListRuleChange } from "./PolicyList"
import BanList, { ChangeType, PolicyRuleChange } from "./PolicyList"
import * as crypto from "crypto";
import { LogService } from "matrix-bot-sdk";
import { EntityType, ListRule } from "./ListRule";
import { EntityType, PolicyRule } from "./PolicyRule";
import PolicyList from "./PolicyList";
export const USER_MAY_INVITE = 'user_may_invite';
@ -149,10 +149,10 @@ export default class RuleServer {
}
/**
* Update the rule server to reflect a ListRule change.
* @param change A ListRuleChange sourced from a BanList.
* Update the rule server to reflect a PolicyRule change.
* @param change A PolicyRuleChange sourced from a BanList.
*/
private applyRuleChange(change: ListRuleChange): void {
private applyRuleChange(change: PolicyRuleChange): void {
if (change.changeType === ChangeType.Added) {
const eventRules = new EventRules(change.event.event_id, change.event.room_id, toRuleServerFormat(change.rule), this.currentToken);
this.addEventRules(eventRules);
@ -208,9 +208,9 @@ export default class RuleServer {
* Process the changes that have been made to a BanList.
* This will ususally be called as a callback from `BanList.onChange`.
* @param banList The BanList that the changes happened in.
* @param changes An array of ListRuleChanges.
* @param changes An array of PolicyRuleChanges.
*/
private update(banList: BanList, changes: ListRuleChange[]) {
private update(banList: BanList, changes: PolicyRuleChange[]) {
if (changes.length > 0) {
this.nextToken();
changes.forEach(this.applyRuleChange, this);
@ -257,11 +257,11 @@ export default class RuleServer {
}
/**
* Convert a ListRule into the format that can be served by the rule server.
* @param policyRule A ListRule to convert.
* Convert a PolicyRule into the format that can be served by the rule server.
* @param policyRule A PolicyRule to convert.
* @returns An array of rules that can be served from the rule server.
*/
function toRuleServerFormat(policyRule: ListRule): RuleServerRule[] {
function toRuleServerFormat(policyRule: PolicyRule): RuleServerRule[] {
function makeLiteral(literal: string) {
return { literal }
}

View File

@ -3,11 +3,11 @@ import { strict as assert } from "assert";
import config from "../../src/config";
import { newTestUser } from "./clientHelper";
import { LogService, MatrixClient, Permalinks, UserID } from "matrix-bot-sdk";
import PolicyList, { ChangeType, ListRuleChange } from "../../src/models/PolicyList";
import PolicyList, { ChangeType, PolicyRuleChange } from "../../src/models/PolicyList";
import { ServerAcl } from "../../src/models/ServerAcl";
import { getFirstReaction } from "./commands/commandUtils";
import { getMessagesByUserIn } from "../../src/utils";
import { ALL_RULE_TYPES, RULE_SERVER, RULE_USER, SERVER_RULE_TYPES } from "../../src/models/ListRule";
import { ALL_RULE_TYPES, RULE_SERVER, RULE_USER, SERVER_RULE_TYPES } from "../../src/models/PolicyRule";
/**
* Create a policy rule in a policy room.
@ -40,7 +40,7 @@ describe("Test: Updating the PolicyList", function() {
// Test adding a new rule
await createPolicyRule(mjolnir, banListId, RULE_USER, '@added:localhost:9999', '');
let changes: ListRuleChange[] = await banList.updateList();
let changes: PolicyRuleChange[] = await banList.updateList();
assert.equal(changes.length, 1, 'There should only be one change');
assert.equal(changes[0].changeType, ChangeType.Added);
assert.equal(changes[0].sender, await mjolnir.getUserId());
@ -187,7 +187,7 @@ describe("Test: Updating the PolicyList", function() {
for (let i = 0; i < ALL_RULE_TYPES.length; i++) {
await createPolicyRule(mjolnir, banListId, ALL_RULE_TYPES[i], `*${i}*`, '');
}
let changes: ListRuleChange[] = await banList.updateList();
let changes: PolicyRuleChange[] = await banList.updateList();
assert.equal(changes.length, ALL_RULE_TYPES.length);
assert.equal(banList.allRules.length, ALL_RULE_TYPES.length);
})
@ -199,7 +199,7 @@ describe('Test: We do not respond to recommendations other than m.ban in the ban
const banListId = await mjolnir.createRoom();
const banList = new PolicyList(banListId, banListId, mjolnir);
await createPolicyRule(mjolnir, banListId, RULE_SERVER, 'exmaple.org', '', { recommendation: 'something that is not m.ban' });
let changes: ListRuleChange[] = await banList.updateList();
let changes: PolicyRuleChange[] = await banList.updateList();
assert.equal(changes.length, 1, 'There should only be one change');
assert.equal(changes[0].changeType, ChangeType.Added);
assert.equal(changes[0].sender, await mjolnir.getUserId());
@ -219,7 +219,7 @@ describe('Test: We will not be able to ban ourselves via ACL.', function() {
await createPolicyRule(mjolnir, banListId, RULE_SERVER, 'evil.com', '');
await createPolicyRule(mjolnir, banListId, RULE_SERVER, '*', '');
// We should still intern the matching rules rule.
let changes: ListRuleChange[] = await banList.updateList();
let changes: PolicyRuleChange[] = await banList.updateList();
assert.equal(banList.serverRules.length, 3);
// But when we construct an ACL, we should be safe.
const acl = new ServerAcl(serverName)