From 199fa2f7c1909f591e81e5329824e0bd9d2de551 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Tue, 5 Jan 2016 18:52:28 -0200 Subject: [PATCH] Implement an interface to manage oauth apps --- i18n/en.i18n.json | 4 +- .../server/startup.coffee | 3 + .../admin/client/collection.coffee | 1 + .../admin/client/route.coffee | 17 +++++ .../admin/client/startup.coffee | 7 ++ .../admin/client/views/oauthApp.coffee | 73 +++++++++++++++++++ .../admin/client/views/oauthApp.html | 51 +++++++++++++ .../admin/client/views/oauthApps.coffee | 9 +++ .../admin/client/views/oauthApps.html | 33 +++++++++ .../admin/server/methods/addOAuthApp.coffee | 25 +++++++ .../server/methods/deleteOAuthApp.coffee | 13 ++++ .../server/methods/updateOAuthApp.coffee | 29 ++++++++ .../admin/server/models/OAuthApps.coffee | 13 ++++ .../server/publications/oauthApps.coffee | 8 ++ .../client/stylesheets/load.coffee | 2 - .../{ => oauth}/client/oauth2-client.coffee | 0 .../{ => oauth}/client/oauth2-client.html | 0 .../oauth/client/stylesheets/load.coffee | 2 + .../client/stylesheets/oauth2.less | 0 .../{ => oauth}/server/oauth2-server.coffee | 0 .../package.js | 24 ++++-- 21 files changed, 306 insertions(+), 8 deletions(-) create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/collection.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/route.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/startup.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html create mode 100644 packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/server/models/OAuthApps.coffee create mode 100644 packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee delete mode 100644 packages/rocketchat-oauth2-server-config/client/stylesheets/load.coffee rename packages/rocketchat-oauth2-server-config/{ => oauth}/client/oauth2-client.coffee (100%) rename packages/rocketchat-oauth2-server-config/{ => oauth}/client/oauth2-client.html (100%) create mode 100644 packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee rename packages/rocketchat-oauth2-server-config/{ => oauth}/client/stylesheets/oauth2.less (100%) rename packages/rocketchat-oauth2-server-config/{ => oauth}/server/oauth2-server.coffee (100%) diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 1853674bef4..d6f8e9c56a2 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -67,6 +67,7 @@ "Add_Members" : "Add Members", "Add_users" : "Add users", "Administration" : "Administration", + "After_OAuth2_authentication_users_will_be_redirected_to_this_URL" : "After OAuth2 authentication, users will be redirected to this URL", "Alias" : "Alias", "All_channels" : "All channels", "Allow_Invalid_SelfSigned_Certs" : "Allow Invalid Self-Signed Certs", @@ -178,6 +179,7 @@ "Get_to_know_the_team" : "Get to know the Rocket.Team", "github_no_public_email" : "You don't have any email as public email in your GitHub account", "Give_a_unique_name_for_the_custom_oauth" : "Give a unique name for the custom oauth", + "Give_the_application_a_name_This_will_be_seen_by_your_users" : "Give the application a name. This will be seen by your users.", "Has_more" : "Has more", "Have_your_own_chat" : "Have your own web chat. Developed with Meteor.com, the Rocket.Chat is a great solution for developers looking forward to build and evolve their own chat platform.", "Hide_room" : "Hide room", @@ -560,7 +562,7 @@ "You_should_name_it_to_easily_manage_your_integrations" : "You should name it to easily manage your integrations.", "You_will_not_be_able_to_recover" : "You will not be able to recover this message!", "Your_entry_has_been_deleted" : "Your entry has been deleted.", - "Your_Open_Source_solution" : "Your own Open Source chat solution", "Your_mail_was_sent_to_s" : "Your mail was sent to %s", + "Your_Open_Source_solution" : "Your own Open Source chat solution", "Your_push_was_sent_to_s_devices" : "Your push was sent to %s devices" } diff --git a/packages/rocketchat-authorization/server/startup.coffee b/packages/rocketchat-authorization/server/startup.coffee index 7e347bdeffb..fbaf7bdb701 100644 --- a/packages/rocketchat-authorization/server/startup.coffee +++ b/packages/rocketchat-authorization/server/startup.coffee @@ -104,6 +104,9 @@ Meteor.startup -> { _id: 'manage-integrations', roles : ['admin', 'bot']} + + { _id: 'manage-oauth-apps', + roles : ['admin']} ] #alanning:roles diff --git a/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee b/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee new file mode 100644 index 00000000000..4004f7cde99 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/collection.coffee @@ -0,0 +1 @@ +@ChatOAuthApps = new Meteor.Collection 'rocketchat_oauth_apps' diff --git a/packages/rocketchat-oauth2-server-config/admin/client/route.coffee b/packages/rocketchat-oauth2-server-config/admin/client/route.coffee new file mode 100644 index 00000000000..f2fcc3b8365 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/route.coffee @@ -0,0 +1,17 @@ +FlowRouter.route '/admin/oauth-apps', + name: 'admin-oauth-apps' + action: (params) -> + BlazeLayout.render 'main', + center: 'pageSettingsContainer' + pageTitle: t('OAuth_Applications') + pageTemplate: 'oauthApps' + + +FlowRouter.route '/admin/oauth-app/:id?', + name: 'admin-oauth-app' + action: (params) -> + BlazeLayout.render 'main', + center: 'pageSettingsContainer' + pageTitle: t('OAuth_Application') + pageTemplate: 'oauthApp' + params: params diff --git a/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee b/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee new file mode 100644 index 00000000000..1619a366a3d --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/startup.coffee @@ -0,0 +1,7 @@ +Meteor.subscribe 'oauthApps' + +RocketChat.AdminBox.addOption + href: 'admin-oauth-apps' + i18nLabel: 'OAuth Apps' + permissionGranted: -> + return RocketChat.authz.hasAllPermission('manage-oauth-apps') diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee new file mode 100644 index 00000000000..d8d3b415c34 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee @@ -0,0 +1,73 @@ +Template.oauthApp.onCreated -> + @record = new ReactiveVar {} + + +Template.oauthApp.helpers + hasPermission: -> + return RocketChat.authz.hasAllPermission 'manage-oauth-apps' + + data: -> + params = Template.instance().data.params?() + + if params?.id? + data = ChatOAuthApps.findOne({_id: params.id}) + if data? + Template.instance().record.set data + return data + + return Template.instance().record.curValue + + +Template.oauthApp.events + "click .submit > .delete": -> + params = Template.instance().data.params() + + swal + title: t('Are_you_sure') + text: t('You_will_not_be_able_to_recover') + type: 'warning' + showCancelButton: true + confirmButtonColor: '#DD6B55' + confirmButtonText: t('Yes_delete_it') + cancelButtonText: t('Cancel') + closeOnConfirm: false + html: false + , -> + Meteor.call "deleteOAuthApp", params.id, (err, data) -> + swal + title: t('Deleted') + text: t('Your_entry_has_been_deleted') + type: 'success' + timer: 1000 + showConfirmButton: false + + FlowRouter.go "admin-oauth-apps" + + "click .submit > .save": -> + name = $('[name=name]').val().trim() + redirectUri = $('[name=redirectUri]').val().trim() + + if name is '' + return toastr.error TAPi18n.__("The_application_name_is_required") + + if redirectUri is '' + return toastr.error TAPi18n.__("The_redirectUri_is_required") + + app = + name: name + redirectUri: redirectUri + + params = Template.instance().data.params?() + if params?.id? + Meteor.call "updateOAuthApp", params.id, app, (err, data) -> + if err? + return toastr.error TAPi18n.__(err.error) + + toastr.success TAPi18n.__("Application_updated") + else + Meteor.call "addOAuthApp", app, (err, data) -> + if err? + return toastr.error TAPi18n.__(err.error) + + toastr.success TAPi18n.__("Application_added") + FlowRouter.go "admin-oauth-app", {id: data._id} diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html new file mode 100644 index 00000000000..fab7358c217 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html @@ -0,0 +1,51 @@ + diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee new file mode 100644 index 00000000000..0dca6796b28 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee @@ -0,0 +1,9 @@ +Template.oauthApps.helpers + hasPermission: -> + return RocketChat.authz.hasAllPermission 'manage-oauth-apps' + + applications: -> + return ChatOAuthApps.find() + + dateFormated: (date) -> + return moment(date).format('L LT') diff --git a/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html new file mode 100644 index 00000000000..f0dc3df3364 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html @@ -0,0 +1,33 @@ + diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee new file mode 100644 index 00000000000..9215823802d --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee @@ -0,0 +1,25 @@ +Meteor.methods + addOAuthApp: (application) -> + if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' + throw new Meteor.Error 'not_authorized' + + if not _.isString(application.name) + throw new Meteor.Error 'invalid_name', '[methods] addOAuthApp -> name must be string' + + if application.name.trim() is '' + throw new Meteor.Error 'invalid_name', '[methods] addOAuthApp -> name can\'t be empty' + + if not _.isString(application.redirectUri) + throw new Meteor.Error 'invalid_redirectUri', '[methods] addOAuthApp -> redirectUri must be string' + + if application.redirectUri.trim() is '' + throw new Meteor.Error 'invalid_redirectUri', '[methods] addOAuthApp -> redirectUri can\'t be empty' + + application.clientId = Random.id() + application.clientSecret = Random.secret() + application._createdAt = new Date + application._createdBy = RocketChat.models.Users.findOne @userId, {fields: {username: 1}} + + application._id = RocketChat.models.OAuthApps.insert application + + return application diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee new file mode 100644 index 00000000000..704dfed09c5 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee @@ -0,0 +1,13 @@ +Meteor.methods + deleteOAuthApp: (applicationId) -> + if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' + throw new Meteor.Error 'not_authorized' + + application = RocketChat.models.OAuthApps.findOne(applicationId) + + if not application? + throw new Meteor.Error 'invalid_application', '[methods] deleteOAuthApp -> application not found' + + RocketChat.models.OAuthApps.remove _id: applicationId + + return true diff --git a/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee new file mode 100644 index 00000000000..300259b18a0 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee @@ -0,0 +1,29 @@ +Meteor.methods + updateOAuthApp: (applicationId, application) -> + if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' + throw new Meteor.Error 'not_authorized' + + if not _.isString(application.name) + throw new Meteor.Error 'invalid_name', '[methods] updateOAuthApp -> name must be string' + + if application.name.trim() is '' + throw new Meteor.Error 'invalid_name', '[methods] updateOAuthApp -> name can\'t be empty' + + if not _.isString(application.redirectUri) + throw new Meteor.Error 'invalid_redirectUri', '[methods] updateOAuthApp -> redirectUri must be string' + + if application.redirectUri.trim() is '' + throw new Meteor.Error 'invalid_redirectUri', '[methods] updateOAuthApp -> redirectUri can\'t be empty' + + currentApplication = RocketChat.models.OAuthApps.findOne(applicationId) + if not currentApplication? + throw new Meteor.Error 'invalid_application', '[methods] updateOAuthApp -> application not found' + + RocketChat.models.OAuthApps.update applicationId, + $set: + name: integration.name + redirectUri: integration.redirectUri + _updatedAt: new Date + _updatedBy: RocketChat.models.Users.findOne @userId, {fields: {username: 1}} + + return RocketChat.models.OAuthApps.findOne(applicationId) diff --git a/packages/rocketchat-oauth2-server-config/admin/server/models/OAuthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/server/models/OAuthApps.coffee new file mode 100644 index 00000000000..5f95a6c2d32 --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/models/OAuthApps.coffee @@ -0,0 +1,13 @@ +RocketChat.models.OAuthApps = new class extends RocketChat.models._Base + constructor: -> + @_initModel 'oauth_apps' + + + # FIND + # findByRole: (role, options) -> + # query = + # roles: role + + # return @find query, options + + # CREATE diff --git a/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee new file mode 100644 index 00000000000..d29a5cbdcdb --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee @@ -0,0 +1,8 @@ +Meteor.publish 'oauthApps', -> + unless @userId + return @ready() + + if not RocketChat.authz.hasPermission @userId, 'manage-oauth-apps' + throw new Meteor.Error "not-authorized" + + return RocketChat.models.OAuthApps.find() diff --git a/packages/rocketchat-oauth2-server-config/client/stylesheets/load.coffee b/packages/rocketchat-oauth2-server-config/client/stylesheets/load.coffee deleted file mode 100644 index 794b9ecd4a0..00000000000 --- a/packages/rocketchat-oauth2-server-config/client/stylesheets/load.coffee +++ /dev/null @@ -1,2 +0,0 @@ -RocketChat.theme.addPackageAsset -> - return Assets.getText 'client/stylesheets/oauth2.less' diff --git a/packages/rocketchat-oauth2-server-config/client/oauth2-client.coffee b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee similarity index 100% rename from packages/rocketchat-oauth2-server-config/client/oauth2-client.coffee rename to packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee diff --git a/packages/rocketchat-oauth2-server-config/client/oauth2-client.html b/packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.html similarity index 100% rename from packages/rocketchat-oauth2-server-config/client/oauth2-client.html rename to packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.html diff --git a/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee new file mode 100644 index 00000000000..631ef382a4e --- /dev/null +++ b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee @@ -0,0 +1,2 @@ +RocketChat.theme.addPackageAsset -> + return Assets.getText 'oauth/client/stylesheets/oauth2.less' diff --git a/packages/rocketchat-oauth2-server-config/client/stylesheets/oauth2.less b/packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/oauth2.less similarity index 100% rename from packages/rocketchat-oauth2-server-config/client/stylesheets/oauth2.less rename to packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/oauth2.less diff --git a/packages/rocketchat-oauth2-server-config/server/oauth2-server.coffee b/packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee similarity index 100% rename from packages/rocketchat-oauth2-server-config/server/oauth2-server.coffee rename to packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee diff --git a/packages/rocketchat-oauth2-server-config/package.js b/packages/rocketchat-oauth2-server-config/package.js index ac5f7ee5319..d1e152e4a11 100644 --- a/packages/rocketchat-oauth2-server-config/package.js +++ b/packages/rocketchat-oauth2-server-config/package.js @@ -16,11 +16,25 @@ Package.onUse(function(api) { api.use('templating', 'client'); api.use('kadira:flow-router', 'client'); - api.addFiles('server/oauth2-server.coffee', 'server'); + api.addFiles('oauth/server/oauth2-server.coffee', 'server'); - api.addFiles('client/oauth2-client.html', 'client'); - api.addFiles('client/oauth2-client.coffee', 'client'); + api.addFiles('oauth/client/oauth2-client.html', 'client'); + api.addFiles('oauth/client/oauth2-client.coffee', 'client'); - api.addAssets('client/stylesheets/oauth2.less', 'server'); - api.addFiles('client/stylesheets/load.coffee', 'server'); + api.addAssets('oauth/client/stylesheets/oauth2.less', 'server'); + api.addFiles('oauth/client/stylesheets/load.coffee', 'server'); + + api.addFiles('admin/client/startup.coffee', 'client'); + api.addFiles('admin/client/collection.coffee', 'client'); + api.addFiles('admin/client/route.coffee', 'client'); + api.addFiles('admin/client/views/oauthApp.html', 'client'); + api.addFiles('admin/client/views/oauthApp.coffee', 'client'); + api.addFiles('admin/client/views/oauthApps.html', 'client'); + api.addFiles('admin/client/views/oauthApps.coffee', 'client'); + + api.addFiles('admin/server/models/OAuthApps.coffee', 'server'); + api.addFiles('admin/server/publications/oauthApps.coffee', 'server'); + api.addFiles('admin/server/methods/addOAuthApp.coffee', 'server'); + api.addFiles('admin/server/methods/updateOAuthApp.coffee', 'server'); + api.addFiles('admin/server/methods/deleteOAuthApp.coffee', 'server'); });