From c340829638e8b1d91caef39a3bfa27ec05311738 Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Fri, 26 Apr 2019 17:54:58 -0300
Subject: [PATCH] Update fetch permissions api (#850)

---
 app/constants/permissions.js                  | 17 ----
 app/lib/methods/getPermissions.js             | 83 ++++++++++++++-----
 .../helpers/mergeSubscriptionsRooms.js        |  5 --
 app/lib/realm.js                              | 22 +----
 app/lib/rocketchat.js                         | 11 ++-
 5 files changed, 69 insertions(+), 69 deletions(-)
 delete mode 100644 app/constants/permissions.js

diff --git a/app/constants/permissions.js b/app/constants/permissions.js
deleted file mode 100644
index 16ce1cfc3..000000000
--- a/app/constants/permissions.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export default [
-	'add-user-to-any-c-room',
-	'add-user-to-any-p-room',
-	'add-user-to-joined-room',
-	'archive-room',
-	'delete-c',
-	'delete-message',
-	'delete-p',
-	'edit-message',
-	'edit-room',
-	'force-delete-message',
-	'mute-user',
-	'set-react-when-readonly',
-	'set-readonly',
-	'unarchive-room',
-	'view-broadcast-member-list'
-];
diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js
index 1ef99eeeb..eaa9da083 100644
--- a/app/lib/methods/getPermissions.js
+++ b/app/lib/methods/getPermissions.js
@@ -1,34 +1,75 @@
 import { InteractionManager } from 'react-native';
+import semver from 'semver';
 
 import database from '../realm';
 import log from '../../utils/log';
-import defaultPermissions from '../../constants/permissions';
+import reduxStore from '../createStore';
+
+const getUpdatedSince = () => {
+	const permissions = database.objects('permissions').sorted('_updatedAt', true)[0];
+	return permissions && permissions._updatedAt.toISOString();
+};
+
+const create = (permissions) => {
+	if (permissions && permissions.length) {
+		permissions.forEach((permission) => {
+			try {
+				database.create('permissions', permission, true);
+			} catch (e) {
+				log('getPermissions create', e);
+			}
+		});
+	}
+};
 
 export default async function() {
 	try {
-		// RC 0.66.0
-		const result = await this.sdk.get('permissions.list');
+		const serverVersion = reduxStore.getState().server.version;
 
-		if (!result.success) {
-			return;
-		}
-		const permissions = result.permissions.filter(permission => defaultPermissions.includes(permission._id));
-		permissions
-			.map((permission) => {
-				permission._updatedAt = new Date();
-				permission.roles = permission.roles.map(role => ({ value: role }));
-				return permission;
+		// if server version is lower than 0.73.0, fetches from old api
+		if (semver.lt(serverVersion, '0.73.0')) {
+			// RC 0.66.0
+			const result = await this.sdk.get('permissions.list');
+			if (!result.success) {
+				return;
+			}
+			InteractionManager.runAfterInteractions(() => {
+				database.write(() => {
+					create(result.permissions);
+				});
 			});
+		} else {
+			const params = {};
+			const updatedSince = getUpdatedSince();
+			if (updatedSince) {
+				params.updatedSince = updatedSince;
+			}
+			// RC 0.73.0
+			const result = await this.sdk.get('permissions.listAll', params);
 
-		InteractionManager.runAfterInteractions(
-			() => database.write(() => permissions.forEach((permission) => {
-				try {
-					database.create('permissions', permission, true);
-				} catch (e) {
-					log('getPermissions create', e);
-				}
-			}))
-		);
+			if (!result.success) {
+				return;
+			}
+
+			InteractionManager.runAfterInteractions(
+				() => database.write(() => {
+					create(result.update);
+
+					if (result.delete && result.delete.length) {
+						result.delete.forEach((p) => {
+							try {
+								const permission = database.objectForPrimaryKey('permissions', p._id);
+								if (permission) {
+									database.delete(permission);
+								}
+							} catch (e) {
+								log('getPermissions delete', e);
+							}
+						});
+					}
+				})
+			);
+		}
 	} catch (e) {
 		log('getPermissions', e);
 	}
diff --git a/app/lib/methods/helpers/mergeSubscriptionsRooms.js b/app/lib/methods/helpers/mergeSubscriptionsRooms.js
index 94dc5f4b8..c09caed51 100644
--- a/app/lib/methods/helpers/mergeSubscriptionsRooms.js
+++ b/app/lib/methods/helpers/mergeSubscriptionsRooms.js
@@ -31,11 +31,6 @@ export const merge = (subscription, room) => {
 			subscription.muted = [];
 		}
 	}
-	if (subscription.roles && subscription.roles.length) {
-		subscription.roles = subscription.roles.map(role => (role.value ? role : { value: role }));
-	} else {
-		subscription.roles = [];
-	}
 
 	if (subscription.mobilePushNotifications === 'nothing') {
 		subscription.notifications = true;
diff --git a/app/lib/realm.js b/app/lib/realm.js
index ee37d1211..8c2bbc547 100644
--- a/app/lib/realm.js
+++ b/app/lib/realm.js
@@ -28,20 +28,12 @@ const settingsSchema = {
 	}
 };
 
-const permissionsRolesSchema = {
-	name: 'permissionsRoles',
-	primaryKey: 'value',
-	properties: {
-		value: 'string'
-	}
-};
-
 const permissionsSchema = {
 	name: 'permissions',
 	primaryKey: '_id',
 	properties: {
 		_id: 'string',
-		roles: { type: 'list', objectType: 'permissionsRoles' },
+		roles: 'string[]',
 		_updatedAt: { type: 'date', optional: true }
 	}
 };
@@ -55,14 +47,6 @@ const roomsSchema = {
 	}
 };
 
-const subscriptionRolesSchema = {
-	name: 'subscriptionRolesSchema',
-	primaryKey: 'value',
-	properties: {
-		value: 'string'
-	}
-};
-
 const userMutedInRoomSchema = {
 	name: 'usersMuted',
 	primaryKey: 'value',
@@ -85,7 +69,7 @@ const subscriptionSchema = {
 		rid: { type: 'string', indexed: true },
 		open: { type: 'bool', optional: true },
 		alert: { type: 'bool', optional: true },
-		roles: { type: 'list', objectType: 'subscriptionRolesSchema' },
+		roles: 'string[]',
 		unread: { type: 'int', optional: true },
 		userMentions: { type: 'int', optional: true },
 		roomUpdatedAt: { type: 'date', optional: true },
@@ -358,7 +342,6 @@ const usersTypingSchema = {
 const schema = [
 	settingsSchema,
 	subscriptionSchema,
-	subscriptionRolesSchema,
 	messagesSchema,
 	threadsSchema,
 	threadMessagesSchema,
@@ -368,7 +351,6 @@ const schema = [
 	attachmentFields,
 	messagesEditedBySchema,
 	permissionsSchema,
-	permissionsRolesSchema,
 	url,
 	frequentlyUsedEmojiSchema,
 	customEmojiAliasesSchema,
diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index d3916642e..27dbc8e9f 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -298,7 +298,8 @@ const RocketChat = {
 				language: result.me.language,
 				status: result.me.status,
 				customFields: result.me.customFields,
-				emails: result.me.emails
+				emails: result.me.emails,
+				roles: result.me.roles
 			};
 			return user;
 		} catch (e) {
@@ -654,7 +655,7 @@ const RocketChat = {
 		return this.sdk.methodCall('getSingleMessage', msgId);
 	},
 	hasPermission(permissions, rid) {
-		let roles = [];
+		let roomRoles = [];
 		try {
 			// get the room from realm
 			const [room] = database.objects('subscriptions').filtered('rid = $0', rid);
@@ -665,15 +666,13 @@ const RocketChat = {
 				}, {});
 			}
 			// get room roles
-			roles = room.roles; // eslint-disable-line prefer-destructuring
+			roomRoles = room.roles;
 		} catch (error) {
 			console.log('hasPermission -> error', error);
 		}
 		// get permissions from realm
 		const permissionsFiltered = database.objects('permissions')
 			.filter(permission => permissions.includes(permission._id));
-		// transform room roles to array
-		const roomRoles = Array.from(Object.keys(roles), i => roles[i].value);
 		// get user roles on the server from redux
 		const userRoles = (reduxStore.getState().login.user && reduxStore.getState().login.user.roles) || [];
 		// merge both roles
@@ -685,7 +684,7 @@ const RocketChat = {
 			result[permission] = false;
 			const permissionFound = permissionsFiltered.find(p => p._id === permission);
 			if (permissionFound) {
-				result[permission] = returnAnArray(permissionFound.roles).some(r => mergedRoles.includes(r.value));
+				result[permission] = returnAnArray(permissionFound.roles).some(r => mergedRoles.includes(r));
 			}
 			return result;
 		}, {});
-- 
GitLab