Allow server admin to get admin bit in room

pull/8756/head
Erik Johnston 2020-11-13 17:51:48 +00:00
parent 34226ec761
commit ae67ff7a37
1 changed files with 99 additions and 2 deletions

View File

@ -14,9 +14,9 @@
# limitations under the License.
import logging
from http import HTTPStatus
from typing import List, Optional
from typing import TYPE_CHECKING, List, Optional
from synapse.api.constants import EventTypes, JoinRules
from synapse.api.constants import EventTypes, JoinRules, Membership
from synapse.api.errors import Codes, NotFoundError, SynapseError
from synapse.http.servlet import (
RestServlet,
@ -34,6 +34,9 @@ from synapse.rest.admin._base import (
from synapse.storage.databases.main.room import RoomSortOrder
from synapse.types import RoomAlias, RoomID, UserID, create_requester
if TYPE_CHECKING:
from synapse.server import HomeServer
logger = logging.getLogger(__name__)
@ -338,3 +341,97 @@ class JoinRoomAliasServlet(RestServlet):
)
return 200, {"room_id": room_id}
class MakeRoomAdminRoomServlet(RestServlet):
PATTERNS = admin_patterns("/make_room_admin/(?P<room_identifier>[^/]*)")
def __init__(self, hs: "HomeServer"):
self.hs = hs
self.auth = hs.get_auth()
self.room_member_handler = hs.get_room_member_handler()
self.event_creation_handler = hs.get_event_creation_handler()
self.state_handler = hs.get_state_handler()
self.is_mine_id = hs.is_mine_id
async def on_POST(self, request, room_identifier):
requester = await self.auth.get_user_by_req(request)
await assert_user_is_admin(self.auth, requester.user)
content = parse_json_object_from_request(request, allow_empty_body=True)
if RoomID.is_valid(room_identifier):
room_id = room_identifier
elif RoomAlias.is_valid(room_identifier):
room_alias = RoomAlias.from_string(room_identifier)
room_id, _ = await self.room_member_handler.lookup_room_alias(room_alias)
room_id = room_id.to_string()
else:
raise SynapseError(
400, "%s was not legal room ID or room alias" % (room_identifier,)
)
user_to_add = content.get("user_id", requester.user.to_string())
room_state = await self.state_handler.get_current_state(room_id)
if not room_state:
raise SynapseError(400, "Server not in room")
create_event = room_state[(EventTypes.Create, "")]
power_levels = room_state.get((EventTypes.PowerLevels, ""))
if power_levels is not None:
admin_users = [
user_id
for user_id, power in power_levels.content.get("users")
if self.is_mine_id(user_id)
]
admin_users.sort(key=lambda user: power_levels.content.get("users")[user])
admin_user_id = admin_users[-1]
pl_content = power_levels.content
else:
admin_user_id = create_event.sender
if not self.is_mine_id(admin_user_id):
raise SynapseError(400, "No local admin user in room")
fake_requester = create_requester(
admin_user_id, authenticated_entity=requester.authenticated_entity,
)
new_pl_content = dict(pl_content)
new_pl_content["users"] = dict(pl_content.get("users", {}))
new_pl_content["users"][user_to_add] = new_pl_content["users"][admin_user_id]
await self.event_creation_handler.create_and_send_nonmember_event(
fake_requester, event_dict=new_pl_content,
)
member_event = room_state.get((EventTypes.Member, user_to_add))
is_joined = False
if member_event:
is_joined = member_event.content["membership"] in (
Membership.JOIN,
Membership.INVITE,
)
if is_joined:
return 200, {}
join_rules = room_state.get((EventTypes.JoinRules, ""))
is_public = False
if join_rules:
is_public = join_rules.content.get("join_rule") == JoinRules.PUBLIC
if is_public:
return 200, {}
await self.room_member_handler.update_membership(
fake_requester,
target=UserID.from_string(user_to_add),
room_id=room_id,
action=Membership.INVITE,
)
return 200, {}