diff --git a/.meteor/packages b/.meteor/packages index 113c4d33f64..ac1dbedc0d0 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -85,3 +85,4 @@ todda00:friendly-slugs underscorestring:underscore.string yasaricli:slugify yasinuslu:blaze-meta +rocketchat:authorization diff --git a/.meteor/versions b/.meteor/versions index b09ffefd8ab..be5c92d0639 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -6,6 +6,7 @@ accounts-meteor-developer@1.0.4 accounts-oauth@1.1.5 accounts-password@1.1.1 accounts-twitter@1.0.4 +alanning:roles@1.2.13 aldeed:simple-schema@1.3.3 arunoda:streams@0.1.17 autoupdate@1.2.1 @@ -100,6 +101,7 @@ reactive-dict@1.1.0 reactive-var@1.0.5 reload@1.1.3 retry@1.0.3 +rocketchat:authorization@0.0.1 rocketchat:autolinker@0.0.1 rocketchat:colors@0.0.1 rocketchat:custom-oauth@1.0.0 diff --git a/client/lib/chatMessages.coffee b/client/lib/chatMessages.coffee index 2ecd8cc4634..15f9289252f 100644 --- a/client/lib/chatMessages.coffee +++ b/client/lib/chatMessages.coffee @@ -40,11 +40,15 @@ class @ChatMessages return -1 edit: (element, index) -> - return unless RocketChat.settings.get 'Message_AllowEditing' + id = element.getAttribute("id") + message = ChatMessage.findOne { _id: id } + hasPermission = RocketChat.authz.hasAtLeastOnePermission('edit-message', message.rid) + editAllowed = RocketChat.settings.get 'Message_AllowEditing' + editOwn = message?.u?._id is Meteor.userId() + + return unless hasPermission or (editAllowed and editOwn) return if element.classList.contains("system") this.clearEditing() - id = element.getAttribute("id") - message = ChatMessage.findOne { _id: id, 'u._id': Meteor.userId() } this.input.value = message.msg this.editing.element = element this.editing.index = index or this.getEditingIndex(element) diff --git a/client/methods/deleteMessage.coffee b/client/methods/deleteMessage.coffee index f6a02bf90b2..24e418d6d28 100644 --- a/client/methods/deleteMessage.coffee +++ b/client/methods/deleteMessage.coffee @@ -3,9 +3,14 @@ Meteor.methods if not Meteor.userId() throw new Meteor.Error 203, t('general.User_logged_out') - if not RocketChat.settings.get 'Message_AllowDeleting' + hasPermission = RocketChat.authz.hasAtLeastOnePermission('delete-message', message.rid) + deleteAllowed = RocketChat.settings.get 'Message_AllowDeleting' + deleteOwn = message?.u?._id is Meteor.userId() + + unless hasPermission or (deleteAllowed and deleteOwn) throw new Meteor.Error 'message-deleting-not-allowed', t('Message_deleting_not_allowed') + Tracker.nonreactive -> ChatMessage.remove _id: message._id diff --git a/client/methods/updateMessage.coffee b/client/methods/updateMessage.coffee index 1366c4e31cd..773bff4a167 100644 --- a/client/methods/updateMessage.coffee +++ b/client/methods/updateMessage.coffee @@ -3,7 +3,13 @@ Meteor.methods if not Meteor.userId() throw new Meteor.Error 203, t('User_logged_out') - if not RocketChat.settings.get 'Message_AllowEditing' + originalMessage = ChatMessage.findOne message._id + + hasPermission = RocketChat.authz.hasAtLeastOnePermission('edit-message', message.rid) + editAllowed = RocketChat.settings.get 'Message_AllowEditing' + editOwn = originalMessage?.u?._id is Meteor.userId() + + unless hasPermission or (editAllowed and editOwn) throw new Meteor.Error 'message-editing-not-allowed', t('Message_editing_not_allowed') Tracker.nonreactive -> diff --git a/client/stylesheets/base.less b/client/stylesheets/base.less index 407cc4eb4da..6bca06133d4 100644 --- a/client/stylesheets/base.less +++ b/client/stylesheets/base.less @@ -2375,14 +2375,14 @@ a.github-fork { display: none; cursor: pointer; } - &.own:hover:not(.system) .edit-message { + &:hover:not(.system) .edit-message { display: inline-block; } .delete-message { display: none; cursor: pointer; } - &.own:hover:not(.system) .delete-message { + &:hover:not(.system) .delete-message { display: inline-block; } .user { diff --git a/client/views/admin/admin.coffee b/client/views/admin/admin.coffee index 07d4c7eaa98..9ab84108dea 100644 --- a/client/views/admin/admin.coffee +++ b/client/views/admin/admin.coffee @@ -1,6 +1,4 @@ Template.admin.helpers - isAdmin: -> - return Meteor.user().admin is true group: -> group = FlowRouter.getParam('group') group ?= Settings.findOne({ type: 'group' })?._id diff --git a/client/views/admin/admin.html b/client/views/admin/admin.html index 9bb7f03c4be..b559af0e10c 100644 --- a/client/views/admin/admin.html +++ b/client/views/admin/admin.html @@ -7,7 +7,7 @@
- {{#unless isAdmin}} + {{#unless hasPermission 'view-privileged-setting'}}

You are not authorized to view this page.

{{else}} {{#with group}} diff --git a/client/views/admin/adminFlex.html b/client/views/admin/adminFlex.html index 164c694c210..cc7ebf87317 100644 --- a/client/views/admin/adminFlex.html +++ b/client/views/admin/adminFlex.html @@ -7,24 +7,35 @@
diff --git a/client/views/admin/adminStatistics.coffee b/client/views/admin/adminStatistics.coffee index 4622e627e50..8c27a0374ef 100644 --- a/client/views/admin/adminStatistics.coffee +++ b/client/views/admin/adminStatistics.coffee @@ -1,6 +1,4 @@ Template.adminStatistics.helpers - isAdmin: -> - return Meteor.user().admin is true isReady: -> return Template.instance().ready.get() statistics: -> diff --git a/client/views/admin/adminStatistics.html b/client/views/admin/adminStatistics.html index fd02286c166..f039362a8ea 100644 --- a/client/views/admin/adminStatistics.html +++ b/client/views/admin/adminStatistics.html @@ -7,7 +7,7 @@
- {{#unless isAdmin}} + {{#unless hasPermission 'view-statistics'}}

You are not authorized to view this page.

{{else}} {{#if isReady}} diff --git a/client/views/admin/rooms/adminRoomInfo.coffee b/client/views/admin/rooms/adminRoomInfo.coffee index ccc7ce451b9..731ea8daf1c 100644 --- a/client/views/admin/rooms/adminRoomInfo.coffee +++ b/client/views/admin/rooms/adminRoomInfo.coffee @@ -1,4 +1,7 @@ Template.adminRoomInfo.helpers + canDeleteRoom: -> + return RocketChat.authz.hasAtLeastOnePermission("delete-#{@t}") + type: -> return if @t is 'd' then 'at' else if @t is 'p' then 'lock' else 'hash' name: -> diff --git a/client/views/admin/rooms/adminRoomInfo.html b/client/views/admin/rooms/adminRoomInfo.html index fc35afc6820..090f36d5e89 100644 --- a/client/views/admin/rooms/adminRoomInfo.html +++ b/client/views/admin/rooms/adminRoomInfo.html @@ -1,14 +1,20 @@ \ No newline at end of file diff --git a/client/views/admin/rooms/adminRooms.coffee b/client/views/admin/rooms/adminRooms.coffee index 82b9995d6da..b871209f475 100644 --- a/client/views/admin/rooms/adminRooms.coffee +++ b/client/views/admin/rooms/adminRooms.coffee @@ -1,6 +1,4 @@ Template.adminRooms.helpers - isAdmin: -> - return Meteor.user().admin is true isReady: -> return Template.instance().ready?.get() rooms: -> diff --git a/client/views/admin/rooms/adminRooms.html b/client/views/admin/rooms/adminRooms.html index e9e35820361..ce0454d58f0 100644 --- a/client/views/admin/rooms/adminRooms.html +++ b/client/views/admin/rooms/adminRooms.html @@ -7,7 +7,7 @@
- {{#unless isAdmin}} + {{#unless hasPermission 'view-room-administration'}}

You are not authorized to view this page.

{{else}}
diff --git a/client/views/admin/users/adminUserChannels.html b/client/views/admin/users/adminUserChannels.html index a2f020d077f..af72dcbbad0 100644 --- a/client/views/admin/users/adminUserChannels.html +++ b/client/views/admin/users/adminUserChannels.html @@ -1,5 +1,9 @@ \ No newline at end of file diff --git a/client/views/admin/users/adminUserEdit.html b/client/views/admin/users/adminUserEdit.html index d00a9875e0c..686f999ffdb 100644 --- a/client/views/admin/users/adminUserEdit.html +++ b/client/views/admin/users/adminUserEdit.html @@ -1,19 +1,23 @@ \ No newline at end of file diff --git a/client/views/admin/users/adminUserInfo.coffee b/client/views/admin/users/adminUserInfo.coffee index 17fef2107ec..90c5bdda538 100644 --- a/client/views/admin/users/adminUserInfo.coffee +++ b/client/views/admin/users/adminUserInfo.coffee @@ -1,6 +1,4 @@ Template.adminUserInfo.helpers - isAdmin: -> - return Meteor.user()?.admin is true name: -> return if @name then @name else TAPi18next.t 'project:Unnamed' email: -> @@ -20,6 +18,9 @@ Template.adminUserInfo.helpers @utcOffset = "+#{@utcOffset}" return "UTC #{@utcOffset}" + hasAdminRole: -> + console.log 'hasAdmin: ', RocketChat.authz.hasRole(@_id, 'admin') + return RocketChat.authz.hasRole(@_id, 'admin') Template.adminUserInfo.events 'click .deactivate': (e) -> diff --git a/client/views/admin/users/adminUserInfo.html b/client/views/admin/users/adminUserInfo.html index 645f560e9d4..bbf17a35256 100644 --- a/client/views/admin/users/adminUserInfo.html +++ b/client/views/admin/users/adminUserInfo.html @@ -1,19 +1,25 @@ \ No newline at end of file diff --git a/client/views/admin/users/adminUsers.coffee b/client/views/admin/users/adminUsers.coffee index 4b4a990af20..d0a05d6ccca 100644 --- a/client/views/admin/users/adminUsers.coffee +++ b/client/views/admin/users/adminUsers.coffee @@ -1,6 +1,4 @@ Template.adminUsers.helpers - isAdmin: -> - return Meteor.user().admin is true isReady: -> return Template.instance().ready?.get() users: -> diff --git a/client/views/admin/users/adminUsers.html b/client/views/admin/users/adminUsers.html index 28921562e11..e85242b85f5 100644 --- a/client/views/admin/users/adminUsers.html +++ b/client/views/admin/users/adminUsers.html @@ -7,7 +7,7 @@
- {{#unless isAdmin}} + {{#unless hasPermission 'view-user-administration'}}

You are not authorized to view this page.

{{else}} diff --git a/client/views/app/message.coffee b/client/views/app/message.coffee index 1b58609d16a..bdd7fb52b13 100644 --- a/client/views/app/message.coffee +++ b/client/views/app/message.coffee @@ -40,9 +40,16 @@ Template.message.helpers pinned: -> return this.pinned canEdit: -> - return RocketChat.settings.get 'Message_AllowEditing' + if RocketChat.authz.hasAtLeastOnePermission('edit-message', this.rid ) + return true + + return RocketChat.settings.get('Message_AllowEditing') and this.u?._id is Meteor.userId() + canDelete: -> - return RocketChat.settings.get 'Message_AllowDeleting' + if RocketChat.authz.hasAtLeastOnePermission('delete-message', this.rid ) + return true + + return RocketChat.settings.get('Message_AllowDeleting') and this.u?._id is Meteor.userId() canPin: -> return RocketChat.settings.get 'Message_AllowPinning' showEditedStatus: -> diff --git a/client/views/app/room.coffee b/client/views/app/room.coffee index 29712c677b1..d71bf3f5407 100644 --- a/client/views/app/room.coffee +++ b/client/views/app/room.coffee @@ -104,7 +104,10 @@ Template.room.helpers canEditName: -> roomData = Session.get('roomData' + this._id) return '' unless roomData - return roomData.u?._id is Meteor.userId() and roomData.t in ['c', 'p'] + if roomData.t in ['c', 'p'] + return RocketChat.authz.hasAtLeastOnePermission('edit-room', this._id) + else + return '' canDirectMessage: -> return Meteor.user()?.username isnt this.username @@ -183,9 +186,6 @@ Template.room.helpers maxMessageLength: -> return RocketChat.settings.get('Message_MaxAllowedSize') - isAdmin: -> - return Meteor.user()?.admin is true - utc: -> if @utcOffset? return "UTC #{@utcOffset}" diff --git a/client/views/app/sideNav/channels.coffee b/client/views/app/sideNav/channels.coffee index 7dffc0db7b2..5d715a1453b 100644 --- a/client/views/app/sideNav/channels.coffee +++ b/client/views/app/sideNav/channels.coffee @@ -10,8 +10,11 @@ Template.channels.helpers Template.channels.events 'click .add-room': (e, instance) -> - SideNav.setFlex "createChannelFlex" - SideNav.openFlex() + if RocketChat.authz.hasAtLeastOnePermission('create-c') + SideNav.setFlex "createChannelFlex" + SideNav.openFlex() + else + e.preventDefault() 'click .more-channels': -> SideNav.setFlex "listChannelsFlex" diff --git a/client/views/app/sideNav/channels.html b/client/views/app/sideNav/channels.html index e4b3cec776b..82defaa8d0d 100644 --- a/client/views/app/sideNav/channels.html +++ b/client/views/app/sideNav/channels.html @@ -1,7 +1,9 @@ diff --git a/client/views/app/sideNav/privateGroups.coffee b/client/views/app/sideNav/privateGroups.coffee index 7e729c5af14..1b577816fe4 100644 --- a/client/views/app/sideNav/privateGroups.coffee +++ b/client/views/app/sideNav/privateGroups.coffee @@ -16,8 +16,11 @@ Template.privateGroups.helpers Template.privateGroups.events 'click .add-room': (e, instance) -> - SideNav.setFlex "privateGroupsFlex" - SideNav.openFlex() + if RocketChat.authz.hasAtLeastOnePermission('create-p') + SideNav.setFlex "privateGroupsFlex" + SideNav.openFlex() + else + e.preventDefault() 'click .more-groups': -> SideNav.setFlex "listPrivateGroupsFlex" diff --git a/client/views/app/sideNav/privateGroups.html b/client/views/app/sideNav/privateGroups.html index 22db34a7c6f..2d5685cc455 100644 --- a/client/views/app/sideNav/privateGroups.html +++ b/client/views/app/sideNav/privateGroups.html @@ -1,7 +1,9 @@