Merge branch 'feature/refactoring_federation' into 'develop'

Feature/refactoring federation

See merge request bwmessenger/bundesmessenger/bundesmessenger-ios!300
This commit is contained in:
JanNiklas Grabowski
2024-01-29 07:45:00 +00:00
8 changed files with 183 additions and 115 deletions

View File

@@ -120,13 +120,12 @@
self.federationImageView.hidden = YES;
}
}
else if (room.isRoomFederated)
{
self.federationImageView.hidden = NO;
}
else
{
self.federationImageView.hidden = YES;
[room getFederationStatusWithCompletion:^(BOOL isFederated) {
self.federationImageView.hidden = !isFederated;
}];
}
}
}

View File

@@ -318,23 +318,30 @@ extension ContactsPickerViewModel: ContactsTableViewControllerDelegate {
if let identifiere = identifieres.first as? String {
// Check if user is federated
if room.isRoomMemberFederated(identifiere) {
// Get current serverACL settings for room
room.getCurrentRoomServerACLSettings { serverACL in
if let serverACL = serverACL {
if serverACL.elementsEqual("*") {
// Federation is active
canInvite = true
} else {
// Federation is deactivated
self.coordinatorDelegate?.contactsPickerViewModel(self, display: "", title: BWIL10n.roomParticipantsInvitePromptFederationForRoomNotAllowedText, actions: [
UIAlertAction(title: VectorL10n.ok, style: .cancel)
])
// Check if room federation flag "isFederated" is true
room.getFederatedFlag { isFederated in
if isFederated {
// Get current serverACL settings for room
self.room.getCurrentRoomServerACLSettings { serverACL in
if let serverACL = serverACL {
if serverACL.elementsEqual("*") {
// Federation is active
canInvite = true
} else {
// Federation is deactivated
self.coordinatorDelegate?.contactsPickerViewModel(self, display: "", title: BWIL10n.roomParticipantsInvitePromptFederationForRoomNotAllowedText, actions:
[UIAlertAction(title: VectorL10n.ok, style: .cancel)])
}
} else {
// ServerACL not configured
self.coordinatorDelegate?.contactsPickerViewModel(self, display: "", title: BWIL10n.roomParticipantsInvitePromptServerAclForRoomNotConfiguredText, actions:
[UIAlertAction(title: VectorL10n.ok, style: .cancel)])
}
}
} else {
// ServerACL not configured
self.coordinatorDelegate?.contactsPickerViewModel(self, display: "", title: BWIL10n.roomParticipantsInvitePromptServerAclForRoomNotConfiguredText, actions: [
UIAlertAction(title: VectorL10n.ok, style: .cancel)
])
// Federation is deactivated
self.coordinatorDelegate?.contactsPickerViewModel(self, display: "", title: BWIL10n.roomParticipantsInvitePromptFederationForRoomNotAllowedText, actions:
[UIAlertAction(title: VectorL10n.ok, style: .cancel)])
}
}
} else {

View File

@@ -44,8 +44,16 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType {
let directUserPresence = session.user(withUserId: room.directUserId)?.presence ?? .unknown
// bwi: 5216 - federation
let isFederated = isFederationEnabled(room: room)
var isFederated = true
let group = DispatchGroup()
group.enter()
self.isFederationEnabled(room: self.room) { federationStatus in
isFederated = federationStatus
group.leave()
}
group.wait()
let basicInfoViewData = RoomInfoBasicViewData(avatarUrl: room.summary.avatar,
mediaManager: session.mediaManager,
roomId: room.roomId,
@@ -66,18 +74,19 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType {
}
// bwi: 5216 - federation
private func isFederationEnabled(room: MXRoom) -> Bool {
private func isFederationEnabled(room: MXRoom, completion: ((_ isFederated: Bool) -> Void)?) {
guard BWIBuildSettings.shared.isFederationEnabled else {
return false
completion?(false)
return
}
if room.isPersonalNotesRoom() {
return false
completion?(false)
} else {
if room.isDirect {
return room.isDMFederated()
completion?(room.isDMFederated())
} else {
return room.isRoomFederated()
room.getFederationStatus(completion: completion)
}
}
}

View File

@@ -8257,35 +8257,37 @@ static CGSize kThreadListBarButtonItemImageSize;
if (!self.roomDataSource.room.isPersonalNotesRoom)
{
// Do not show sheet if isFederated room flag is false (default == true)
if (self.roomDataSource.room.isRoomFederated)
{
// Do not show sheet if users power level is lower than admin
MXRoomPowerLevels *powerLevels = self.roomDataSource.roomState.powerLevels;
if ([powerLevels powerLevelOfUserWithUserID:self.mainSession.myUser.userId] >= RoomPowerLevelAdmin)
[self.roomDataSource.room getFederatedFlagWithCompletion:^(BOOL isFederated) {
if (isFederated)
{
// Show sheet if no serverACL have been configured
[self.roomDataSource.room getCurrentRoomServerACLSettingsWithCompletion:^(NSString *serverACL)
{
if (serverACL == nil) {
self.wasFederationDecisionSheetShownBefore = true;
RoomFederationDecisionSheet *federationDecisionView = [[RoomFederationDecisionSheet alloc] init];
UIImage *roomAvatarImage;
MXKImageView *roomAvatarImageView = ((RoomTitleView*)self.titleView).pictureView;
if (roomAvatarImageView && roomAvatarImageView.image)
{
roomAvatarImage = roomAvatarImageView.image;
// Do not show sheet if users power level is lower than admin
MXRoomPowerLevels *powerLevels = self.roomDataSource.roomState.powerLevels;
if ([powerLevels powerLevelOfUserWithUserID:self.mainSession.myUser.userId] >= RoomPowerLevelAdmin)
{
// Show sheet if no serverACL have been configured
[self.roomDataSource.room getCurrentRoomServerACLSettingsWithCompletion:^(NSString *serverACL)
{
if (serverACL == nil) {
self.wasFederationDecisionSheetShownBefore = true;
RoomFederationDecisionSheet *federationDecisionView = [[RoomFederationDecisionSheet alloc] init];
UIImage *roomAvatarImage;
MXKImageView *roomAvatarImageView = ((RoomTitleView*)self.titleView).pictureView;
if (roomAvatarImageView && roomAvatarImageView.image)
{
roomAvatarImage = roomAvatarImageView.image;
}
else
{
roomAvatarImage = [AvatarGenerator generateAvatarForMatrixItem:self.roomDataSource.roomId withDisplayName:self.roomDataSource.room.summary.displayName];
}
UIViewController *sheetViewController = [federationDecisionView makeViewControllerWithRoom:self.roomDataSource.room roomAvatarImage: roomAvatarImage];
sheetViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:sheetViewController animated:YES completion:nil];
}
else
{
roomAvatarImage = [AvatarGenerator generateAvatarForMatrixItem:self.roomDataSource.roomId withDisplayName:self.roomDataSource.room.summary.displayName];
}
UIViewController *sheetViewController = [federationDecisionView makeViewControllerWithRoom:self.roomDataSource.room roomAvatarImage: roomAvatarImage];
sheetViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:sheetViewController animated:YES completion:nil];
}
}];
}];
}
}
}
}];
}
}
}

View File

@@ -605,8 +605,23 @@ BOOL reloadToggleCell = false;
[tmpSections addObject:[self sectionForAccessSwitch]];
}
if ( BWIBuildSettings.shared.isFederationEnabled && !mxRoom.isDirect){
[tmpSections addObject:[self sectionForFederationSwitch]];
if (BWIBuildSettings.shared.isFederationEnabled)
{
// Do not show federation settings for DMs
if (!mxRoom.isDirect)
{
// Do not show federation settings for personal note room
if (!mxRoom.isPersonalNotesRoom)
{
// Show federation settings if "isFederated" flag is true (default == true)
[mxRoom getFederatedFlagWithCompletion:^(BOOL isFederated) {
if (isFederated)
{
[tmpSections addObject:[self sectionForFederationSwitch]];
}
}];
}
}
}
if (RiotSettings.shared.roomSettingsScreenAllowChangingHistorySettings)
@@ -1693,10 +1708,8 @@ BOOL reloadToggleCell = false;
NSString *serverACLRule = updatedItemsDict[kRoomSettingsFederationKey];
if (serverACLRule)
{
NSMutableDictionary *content = [[NSMutableDictionary alloc] initWithDictionary:@{
@"allow": @[serverACLRule],
@"allowIPLiterals" : @false
}];
NSDictionary *content = [mxRoom createServerACLContentWithServerACL:serverACLRule];
pendingOperation = [mxRoom sendStateEventOfType:kMXEventTypeStringRoomServerACL content:content stateKey:nil success:^(NSString *eventId) {
if (weakSelf)

View File

@@ -146,33 +146,43 @@
// bwi: #5226 us12 add federation icons to navigationViewTitle
if (self.pillImageView)
{
if ([self.mxRoom isDirect])
if (![self.mxRoom isPersonalNotesRoom])
{
if ([self.mxRoom isDMFederated])
if ([self.mxRoom isDirect])
{
self.pillImageView.hidden = false;
self.displayNameTextField.rightViewMode = UITextFieldViewModeAlways;
self.displayNameTextField.rightView = [FederationIconHelper.shared getRoomFederationPillViewWithTextView:self.displayNameTextField];
if ([self.mxRoom isDMFederated])
{
self.pillImageView.hidden = false;
self.displayNameTextField.rightViewMode = UITextFieldViewModeAlways;
self.displayNameTextField.rightView = [FederationIconHelper.shared getRoomFederationPillViewWithTextView:self.displayNameTextField];
}
else
{
self.pillImageView.hidden = true;
self.displayNameTextField.rightViewMode = UITextFieldViewModeNever;
}
}
else
{
self.pillImageView.hidden = true;
self.displayNameTextField.rightViewMode = UITextFieldViewModeNever;
[self.mxRoom getFederationStatusWithCompletion:^(BOOL isFederated) {
if (isFederated)
{
self.pillImageView.hidden = false;
self.displayNameTextField.rightViewMode = UITextFieldViewModeAlways;
self.displayNameTextField.rightView = [FederationIconHelper.shared getRoomFederationPillViewWithTextView:self.displayNameTextField];
}
else
{
self.pillImageView.hidden = true;
self.displayNameTextField.rightViewMode = UITextFieldViewModeNever;
}
}];
}
}
else
{
if ([self.mxRoom isRoomFederated])
{
self.pillImageView.hidden = false;
self.displayNameTextField.rightViewMode = UITextFieldViewModeAlways;
self.displayNameTextField.rightView = [FederationIconHelper.shared getRoomFederationPillViewWithTextView:self.displayNameTextField];
}
else
{
self.pillImageView.hidden = true;
self.displayNameTextField.rightViewMode = UITextFieldViewModeNever;
}
self.pillImageView.hidden = true;
self.displayNameTextField.rightViewMode = UITextFieldViewModeNever;
}
}

View File

@@ -20,37 +20,31 @@ import MatrixSDK
@objc extension MXRoom {
func isRoomFederated() -> Bool {
var isFederated: Bool = true
state { state in
// Search for federate flag. If the flag is not found, default value is true
if let events = state?.stateEvents(with: .roomCreate) {
for event in events {
if let federateContentValue = event.wireContent["m.federate"] {
isFederated = federateContentValue as? Bool ?? true
}
}
}
if isFederated {
// Federation status for room, "isFederated" flag + serverACL
func getFederationStatus(completion: ((_ isFederated:Bool) -> Void)?) {
var federationStatus = true
// Get federated flag
getFederatedFlag { isFederated in
federationStatus = isFederated
if federationStatus {
// Check Server ACLs
if let events = state?.stateEvents(with: .roomServerACL) {
let myUserId = self.mxSession.myUser.userId ?? ""
let myUserIdComponents = myUserId.components(separatedBy: ":")
if let event = events.last {
if let allowedServerList = event.wireContent["allow"] as? [String] {
if allowedServerList.count == 1 {
if allowedServerList[0] != "*" && myUserIdComponents.count == 2 && allowedServerList[0] == myUserIdComponents.last ?? "" {
isFederated = false
}
}
self.getCurrentRoomServerACLSettings { serverACL in
if let serverACL = serverACL {
let myUserId = self.mxSession.myUser.userId ?? ""
let myUserIdComponents = myUserId.components(separatedBy: ":")
if serverACL != "*" && myUserIdComponents.count == 2 && serverACL == myUserIdComponents.last ?? "" {
federationStatus = false
}
}
completion?(federationStatus)
}
} else {
completion?(federationStatus)
}
}
return isFederated
}
func isDMFederated() -> Bool {
var isFederated: Bool = false
// Check if the user is from the same homeserver
@@ -81,6 +75,23 @@ import MatrixSDK
return isFederated
}
// Get "isFederated" flag for room, default == true
func getFederatedFlag(completion: ((_ isFederated: Bool) -> Void)?) {
state { state in
var isFederated = true
// Search for federate flag. If the flag is not found, default value is true
if let events = state?.stateEvents(with: .roomCreate) {
for event in events {
if let federateContentValue = event.wireContent["m.federate"] {
isFederated = federateContentValue as? Bool ?? true
}
}
}
completion?(isFederated)
}
}
// Get serverACL for room
func getCurrentRoomServerACLSettings(completion: ((_ serverACL: String?)-> Void)?) {
state { state in
if let events = state?.stateEvents(with: .roomServerACL) {
@@ -96,6 +107,9 @@ import MatrixSDK
// No ServerACL settings found
completion?(nil)
}
} else {
// No ServerACL settings found
completion?(nil)
}
} else {
// No ServerACL settings found
@@ -103,4 +117,32 @@ import MatrixSDK
}
}
}
// Create map for content json with boolean
func createServerACL(isFederated: Bool) -> [String:Any] {
var serverACL: String = ""
if isFederated {
serverACL = "*"
} else {
if let myUserIDComponents = self.mxSession.myUserId?.components(separatedBy: ":")
{
if myUserIDComponents.count == 2 {
serverACL = myUserIDComponents[1]
}
}
}
return createServerACLContent(serverACL: serverACL)
}
// Create map for content json with serverACL string
func createServerACLContent(serverACL: String) -> [String:Any] {
var content: [String:Any] = [String:Any]()
var serverACLList: [String] = [String]()
serverACLList.append(serverACL)
content.updateValue(serverACLList, forKey: "allow")
content.updateValue(false, forKey: "allow_ip_literals")
return content
}
}

View File

@@ -161,21 +161,7 @@ struct RoomFederationDecisionView: View {
func setServerACL(isFederated: Bool) {
var serverACL: [String] = [String]()
if isFederated {
serverACL.append("*")
} else {
if let myUserIDComponents = room.mxSession.myUserId?.components(separatedBy: ":")
{
if myUserIDComponents.count == 2 {
serverACL.append(myUserIDComponents[1])
}
}
}
var content: [String:Any] = [String:Any]()
content.updateValue(serverACL, forKey: "allow")
content.updateValue(false, forKey: "allowIPLiterals")
let content: [String:Any] = room.createServerACL(isFederated: isFederated)
isUpdatingServerACLs = true
pendingRequest = room.sendStateEvent(MXEventType.roomServerACL, content: content, stateKey: "") { response in
isUpdatingServerACLs = false