mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
Refactor list creation with MSC3784 support.
https://github.com/matrix-org/matrix-spec-proposals/pull/3784 This was extracted from the appservice mjolnir work to reduce review burden.
This commit is contained in:
parent
5bd23ced9b
commit
18d2f5fceb
@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import { Mjolnir } from "../Mjolnir";
|
||||
import { SHORTCODE_EVENT_TYPE } from "../models/PolicyList";
|
||||
import PolicyList from "../models/PolicyList";
|
||||
import { Permalinks, RichReply } from "matrix-bot-sdk";
|
||||
|
||||
// !mjolnir list create <shortcode> <alias localpart>
|
||||
@ -23,34 +23,12 @@ export async function execCreateListCommand(roomId: string, event: any, mjolnir:
|
||||
const shortcode = parts[3];
|
||||
const aliasLocalpart = parts[4];
|
||||
|
||||
const powerLevels: { [key: string]: any } = {
|
||||
"ban": 50,
|
||||
"events": {
|
||||
"m.room.name": 100,
|
||||
"m.room.power_levels": 100,
|
||||
},
|
||||
"events_default": 50, // non-default
|
||||
"invite": 0,
|
||||
"kick": 50,
|
||||
"notifications": {
|
||||
"room": 20,
|
||||
},
|
||||
"redact": 50,
|
||||
"state_default": 50,
|
||||
"users": {
|
||||
[await mjolnir.client.getUserId()]: 100,
|
||||
[event["sender"]]: 50
|
||||
},
|
||||
"users_default": 0,
|
||||
};
|
||||
|
||||
const listRoomId = await mjolnir.client.createRoom({
|
||||
preset: "public_chat",
|
||||
room_alias_name: aliasLocalpart,
|
||||
invite: [event['sender']],
|
||||
initial_state: [{ type: SHORTCODE_EVENT_TYPE, state_key: "", content: { shortcode: shortcode } }],
|
||||
power_level_content_override: powerLevels,
|
||||
});
|
||||
const listRoomId = await PolicyList.createList(
|
||||
mjolnir.client,
|
||||
shortcode,
|
||||
[event['sender']],
|
||||
{ room_alias_name: aliasLocalpart }
|
||||
);
|
||||
|
||||
const roomRef = Permalinks.forRoom(listRoomId);
|
||||
await mjolnir.watchList(roomRef);
|
||||
|
@ -86,6 +86,10 @@ class PolicyList extends EventEmitter {
|
||||
// Events that we have already informed the batcher about, that we haven't loaded from the room state yet.
|
||||
private batchedEvents = new Set<string /* event id */>();
|
||||
|
||||
/** MSC3784 support. Please note that policy lists predate room types. So there will be lists in the wild without this type. */
|
||||
public static readonly ROOM_TYPE = "support.feline.policy.lists.msc.v1";
|
||||
public static readonly ROOM_TYPE_VARIANTS = [PolicyList.ROOM_TYPE]
|
||||
|
||||
/**
|
||||
* This is used to annotate state events we store with the rule they are associated with.
|
||||
* If we refactor this, it is important to also refactor any listeners to 'PolicyList.update'
|
||||
@ -105,6 +109,65 @@ class PolicyList extends EventEmitter {
|
||||
this.batcher = new UpdateBatcher(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new policy list.
|
||||
* @param client A MatrixClient that will be used to create the list.
|
||||
* @param shortcode A shortcode to refer to the list with.
|
||||
* @param invite A list of users to invite to the list and make moderator.
|
||||
* @param createRoomOptions Additional room create options such as an alias.
|
||||
* @returns The room id for the newly created policy list.
|
||||
*/
|
||||
public static async createList(
|
||||
client: MatrixClient,
|
||||
shortcode: string,
|
||||
invite: string[],
|
||||
createRoomOptions = {}
|
||||
): Promise<string /* room id */> {
|
||||
const powerLevels: { [key: string]: any } = {
|
||||
"ban": 50,
|
||||
"events": {
|
||||
"m.room.name": 100,
|
||||
"m.room.power_levels": 100,
|
||||
},
|
||||
"events_default": 50, // non-default
|
||||
"invite": 0,
|
||||
"kick": 50,
|
||||
"notifications": {
|
||||
"room": 20,
|
||||
},
|
||||
"redact": 50,
|
||||
"state_default": 50,
|
||||
"users": {
|
||||
[await client.getUserId()]: 100,
|
||||
...invite.reduce((users, mxid) => ({...users, [mxid]: 50 }), {}),
|
||||
},
|
||||
"users_default": 0,
|
||||
};
|
||||
const finalRoomCreateOptions = {
|
||||
// Support for MSC3784.
|
||||
creation_content: {
|
||||
type: PolicyList.ROOM_TYPE
|
||||
},
|
||||
preset: "public_chat",
|
||||
invite,
|
||||
initial_state: [
|
||||
{
|
||||
type: SHORTCODE_EVENT_TYPE,
|
||||
state_key: "",
|
||||
content: {shortcode: shortcode}
|
||||
}
|
||||
],
|
||||
power_level_content_override: powerLevels,
|
||||
...createRoomOptions
|
||||
};
|
||||
// Guard room type in case someone overwrites it when declaring custom creation_content in future code.
|
||||
if (!PolicyList.ROOM_TYPE_VARIANTS.includes(finalRoomCreateOptions.creation_content.type)) {
|
||||
throw new TypeError(`Creating a policy room with a type other than the policy room type is not supported, you probably don't want to do this.`);
|
||||
}
|
||||
const listRoomId = await client.createRoom(finalRoomCreateOptions);
|
||||
return listRoomId
|
||||
}
|
||||
|
||||
/**
|
||||
* The code that can be used to refer to this banlist in Mjolnir commands.
|
||||
*/
|
||||
|
@ -8,6 +8,7 @@ import { getMessagesByUserIn } from "../../src/utils";
|
||||
import { Mjolnir } from "../../src/Mjolnir";
|
||||
import { ALL_RULE_TYPES, Recommendation, RULE_SERVER, RULE_USER, SERVER_RULE_TYPES } from "../../src/models/ListRule";
|
||||
import AccessControlUnit, { Access, EntityAccess } from "../../src/models/AccessControlUnit";
|
||||
import { randomUUID } from "crypto";
|
||||
|
||||
/**
|
||||
* Create a policy rule in a policy room.
|
||||
@ -564,3 +565,31 @@ describe('Test: AccessControlUnit interaction with policy lists.', function() {
|
||||
assertAccess(Access.Allowed, aclUnit.getAccessForServer(banMeServer), "Should not longer be any rules");
|
||||
})
|
||||
})
|
||||
|
||||
describe('Test: Creating policy lists.', function() {
|
||||
it('Will automatically invite and op users from invites', async function() {
|
||||
const mjolnir: Mjolnir = this.mjolnir;
|
||||
const testUsers = await Promise.all([...Array(2)].map(_ => newTestUser(this.config.homeserverUrl, { name: { contains: "moderator" } })))
|
||||
const invite = await Promise.all(testUsers.map(client => client.getUserId()));
|
||||
const policyListId = await PolicyList.createList(
|
||||
mjolnir.client,
|
||||
randomUUID(),
|
||||
invite
|
||||
);
|
||||
// Check power levels are right.
|
||||
const powerLevelEvent = await mjolnir.client.getRoomStateEvent(policyListId, "m.room.power_levels", "");
|
||||
assert.equal(Object.keys(powerLevelEvent.users ?? {}).length, invite.length + 1);
|
||||
// Check create event for MSC3784 support.
|
||||
const createEvent = await mjolnir.client.getRoomStateEvent(policyListId, "m.room.create", "");
|
||||
assert.equal(createEvent.type, PolicyList.ROOM_TYPE);
|
||||
// We can't create rooms without forgetting the type.
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await PolicyList.createList(mjolnir.client, randomUUID(), [], {
|
||||
creation_content: {}
|
||||
})
|
||||
},
|
||||
TypeError
|
||||
);
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user