Feat: create rooms for labs
ci/woodpecker/push/woodpecker Pipeline is pending Details

main
Dorian Zedler 2022-09-29 22:13:09 +02:00
parent f9bd2a46a1
commit 8018958090
Signed by: dozedler
GPG Key ID: 989DE36109AFA354
3 changed files with 54 additions and 28 deletions

View File

@ -9,9 +9,10 @@ A Matrix-Bot which is able to:
1. create default rooms 1. create default rooms
2. load users and their groups from matrix and ldap 2. load users and their groups from matrix and ldap
3. create rooms for all projects which have `sophomorixMailList=TRUE` 3. create rooms for all projects which end in `lab`
4. load all rooms (created by the bot) and their power levels from matrix 4. create rooms for all projects which have `sophomorixMailList=TRUE`
5. sync user memberships and power levels 5. load all rooms (created by the bot) and their power levels from matrix
6. sync user memberships and power levels
# How to use # How to use

View File

@ -35,6 +35,7 @@ class MlmMatrixBot:
async def run(self): async def run(self):
self._current_log_step = 0
logging.info("==> Sync started <==") logging.info("==> Sync started <==")
await self._create_default_rooms() await self._create_default_rooms()
@ -43,7 +44,9 @@ class MlmMatrixBot:
await self._create_project_rooms(all_projects) await self._create_project_rooms(all_projects)
logging.info("= (4/5) Loading current rooms =") await self._create_lab_rooms()
self._log_step("Loading current rooms")
matrix_rooms = await self._get_managed_rooms(with_power_levels=True) matrix_rooms = await self._get_managed_rooms(with_power_levels=True)
matrix_room_ids = list(map(lambda room: room['id'], matrix_rooms)) matrix_room_ids = list(map(lambda room: room['id'], matrix_rooms))
room_name_id_map = {} room_name_id_map = {}
@ -53,7 +56,7 @@ class MlmMatrixBot:
room_name_id_map[room['name']] = room['id'] room_name_id_map[room['name']] = room['id']
room_id_map[room['id']] = room room_id_map[room['id']] = room
logging.info("= (5/5) Syncing user memberships =") self._log_step("Syncing user memberships")
for user in current_users: for user in current_users:
if not "mlm" in user['groups']: if not "mlm" in user['groups']:
continue continue
@ -76,14 +79,14 @@ class MlmMatrixBot:
if room_id in user['rooms']: if room_id in user['rooms']:
continue continue
logging.info(f"\t* joining {room_id_map[room_id]['name']}") logging.info(f"\t\t* joining {room_id_map[room_id]['name']}")
await self._matrixHelper.add_user_to_room(user['matrix_username'], room_id) await self._matrixHelper.add_user_to_room(user['matrix_username'], room_id)
# remove from rooms that are not in the groups # remove from rooms that are not in the groups
rooms_to_be_left = list(filter( rooms_to_be_left = list(filter(
lambda room: room in matrix_room_ids and not room in rooms_to_join, user['rooms'])) lambda room: room in matrix_room_ids and not room in rooms_to_join, user['rooms']))
for room_id in rooms_to_be_left: for room_id in rooms_to_be_left:
logging.info(f"\t* leaving {room_id_map[room_id]['name']}") logging.info(f"\t\t* leaving {room_id_map[room_id]['name']}")
await self._matrixHelper.remove_user_from_room( await self._matrixHelper.remove_user_from_room(
user['matrix_username'], room_id) user['matrix_username'], room_id)
@ -101,7 +104,7 @@ class MlmMatrixBot:
async def _create_default_rooms(self): async def _create_default_rooms(self):
# create default rooms # create default rooms
logging.info("= (1/5) Creating default rooms =") self._log_step("Creating default rooms")
await self._create_rooms(self._get_default_rooms()) await self._create_rooms(self._get_default_rooms())
async def _load_users_and_groups(self): async def _load_users_and_groups(self):
@ -122,7 +125,7 @@ class MlmMatrixBot:
'p_3d-printing' 'p_3d-printing'
]) ])
""" """
logging.info("= (2/5) Loading users and their groups =") self._log_step("Loading users and their groups")
matrix_users = await self._matrixHelper.get_users() matrix_users = await self._matrixHelper.get_users()
current_users = [] current_users = []
all_projects = [] all_projects = []
@ -166,17 +169,28 @@ class MlmMatrixBot:
return current_users, all_projects return current_users, all_projects
async def _create_project_rooms(self, projects): async def _create_project_rooms(self, projects):
logging.info("= (3/5) Creating project rooms =") self._log_step("Creating project rooms")
projects = list( projects = list(
map(lambda project: project.replace('p_', ''), projects)) map(lambda project: project.replace('p_', ''), projects))
await self._create_rooms(projects) await self._create_rooms(projects)
async def _create_rooms(self, rooms): async def _create_lab_rooms(self):
self._log_step("Creating lab rooms")
rc, labs = self._ldapHelper.search(
f"(&(sophomorixType=project)(sAMAccountName=*lab))", ['sAMAccountName'])
if not rc:
return
labs = list(map(lambda lab: lab['sAMAccountName'].replace("p_", "").replace("lab", "-lab"), labs))
await self._create_rooms(labs, joinable_for_space_members=True)
async def _create_rooms(self, rooms, joinable_for_space_members=False, suggested=False):
matrix_room_names = list(map(lambda room: room['name'], await self._get_managed_rooms())) matrix_room_names = list(map(lambda room: room['name'], await self._get_managed_rooms()))
for room in rooms: for room in rooms:
if room not in matrix_room_names: if room not in matrix_room_names:
logging.info(f"* Creating room {room}") logging.info(f"* Creating room {room}")
await self._matrixHelper.create_room(room, room) await self._matrixHelper.create_room(room, room, joinable_for_space_members=joinable_for_space_members, suggested=True)
async def _get_managed_rooms(self, with_power_levels=False): async def _get_managed_rooms(self, with_power_levels=False):
matrix_rooms = await self._matrixHelper.get_rooms() matrix_rooms = await self._matrixHelper.get_rooms()
@ -197,6 +211,10 @@ class MlmMatrixBot:
def _get_default_rooms(self): def _get_default_rooms(self):
return self._config['DEFAULT_ROOMS'].split(',') return self._config['DEFAULT_ROOMS'].split(',')
def _log_step(self, message):
logging.info(f"= ({self._current_log_step}/6) {message} =")
self._current_log_step += 1
def _readConfig(self): def _readConfig(self):
requiredConfigKeys = [ requiredConfigKeys = [
'MATRIX_BOT_LDAP_URI', 'MATRIX_BOT_LDAP_URI',

View File

@ -57,27 +57,16 @@ class MatrixHelper:
async def logout(self): async def logout(self):
await self._client.close() await self._client.close()
async def create_room(self, name, alias, joinable_for_space_members=False): async def create_room(self, name, alias, joinable_for_space_members=False, suggested=False):
# we not only need to create the room but also have to add it to the space # we not only need to create the room but also have to add it to the space
via_domain = self._space_id.split(":")[1]
initial_state = [ initial_state = [
{ {
"type": "m.space.parent", "type": "m.space.parent",
"state_key": self._space_id, "state_key": self._space_id,
"content": { "content": {
"canonical": True, "canonical": True,
"via": [self._space_id.split(":")[1]], "via": [via_domain],
}
},
{
"type": "m.room.join_rules",
"content": {
"join_rule": "restricted",
"allow": [
{
"type": "m.room_membership",
"room_id": self._space_id
}
]
} }
}, },
{ {
@ -95,16 +84,34 @@ class MatrixHelper:
] ]
if joinable_for_space_members: if joinable_for_space_members:
initial_state.append({ initial_state.insert(0, {
"type": "m.room.guest_access", "type": "m.room.guest_access",
"state_key": "", "state_key": "",
"content": {"guest_access": "can_join"} "content": {"guest_access": "can_join"}
}) })
initial_state.insert(2, {
"type": "m.room.join_rules",
"content": {
"join_rule": "restricted",
"allow": [
{
"type": "m.room_membership",
"room_id": self._space_id
}
]
}
})
room = await self._client.room_create(visibility=nio.RoomVisibility.private, name=name, alias=alias, federate=False, initial_state=initial_state) room = await self._client.room_create(visibility=nio.RoomVisibility.private, name=name, alias=alias, federate=False, initial_state=initial_state)
assert room.room_id is not None assert room.room_id is not None
# add as child room
state_update = await self._client.room_put_state(self._space_id, "m.space.child", {
"suggested": suggested,
"via": [via_domain],
}, state_key=room.room_id)
assert state_update.event_id is not None
return room return room
async def get_rooms(self): async def get_rooms(self):