Implement an interface to manage oauth apps

pull/1810/head
Rodrigo Nascimento 10 years ago
parent dfa4358a6a
commit 199fa2f7c1
  1. 4
      i18n/en.i18n.json
  2. 3
      packages/rocketchat-authorization/server/startup.coffee
  3. 1
      packages/rocketchat-oauth2-server-config/admin/client/collection.coffee
  4. 17
      packages/rocketchat-oauth2-server-config/admin/client/route.coffee
  5. 7
      packages/rocketchat-oauth2-server-config/admin/client/startup.coffee
  6. 73
      packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.coffee
  7. 51
      packages/rocketchat-oauth2-server-config/admin/client/views/oauthApp.html
  8. 9
      packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.coffee
  9. 33
      packages/rocketchat-oauth2-server-config/admin/client/views/oauthApps.html
  10. 25
      packages/rocketchat-oauth2-server-config/admin/server/methods/addOAuthApp.coffee
  11. 13
      packages/rocketchat-oauth2-server-config/admin/server/methods/deleteOAuthApp.coffee
  12. 29
      packages/rocketchat-oauth2-server-config/admin/server/methods/updateOAuthApp.coffee
  13. 13
      packages/rocketchat-oauth2-server-config/admin/server/models/OAuthApps.coffee
  14. 8
      packages/rocketchat-oauth2-server-config/admin/server/publications/oauthApps.coffee
  15. 2
      packages/rocketchat-oauth2-server-config/client/stylesheets/load.coffee
  16. 0
      packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.coffee
  17. 0
      packages/rocketchat-oauth2-server-config/oauth/client/oauth2-client.html
  18. 2
      packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/load.coffee
  19. 0
      packages/rocketchat-oauth2-server-config/oauth/client/stylesheets/oauth2.less
  20. 0
      packages/rocketchat-oauth2-server-config/oauth/server/oauth2-server.coffee
  21. 24
      packages/rocketchat-oauth2-server-config/package.js

@ -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"
}

@ -104,6 +104,9 @@ Meteor.startup ->
{ _id: 'manage-integrations',
roles : ['admin', 'bot']}
{ _id: 'manage-oauth-apps',
roles : ['admin']}
]
#alanning:roles

@ -0,0 +1 @@
@ChatOAuthApps = new Meteor.Collection 'rocketchat_oauth_apps'

@ -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

@ -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')

@ -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}

@ -0,0 +1,51 @@
<template name="oauthApp">
<div class="permissions-manager">
{{#if hasPermission}}
<a href="{{pathFor "admin-oauth-apps"}}"><i class="icon-angle-left"></i> {{_ "Back_to_applications"}}</a><br><br>
<div class="rocket-form">
<div class="section">
<div class="section-content">
<div class="input-line double-col">
<label>{{_ "Application_Name"}}</label>
<div>
<input type="text" name="name" value="{{data.name}}" placeholder="{{_ 'Optional'}}" />
<div class="settings-description">{{_ "Give_the_application_a_name_This_will_be_seen_by_your_users"}}</div>
</div>
</div>
<div class="input-line double-col">
<label>{{_ "Redirect_URI"}}</label>
<div>
<input type="text" name="redirectUri" value="{{data.redirectUri}}" />
<div class="settings-description">{{_ "After_OAuth2_authentication_users_will_be_redirected_to_this_URL"}}</div>
</div>
</div>
{{#if data.clientId}}
<div class="input-line double-col">
<label>{{_ "Client_ID"}}</label>
<div>
<input type="text" name="clientId" value="{{data.clientId}}" disabled="disabled" />
<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=clientId]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
</div>
</div>
<div class="input-line double-col">
<label>{{_ "Client_Secret"}}</label>
<div>
<input type="text" name="clientSecret" value="{{data.clientSecret}}" disabled="disabled" />
<div class="settings-description"><a href="#" class="clipboard" data-clipboard-target="[name=clientSecret]">{{_ "COPY_TO_CLIPBOARD"}}</a></div>
</div>
</div>
{{/if}}
</div>
</div>
<div class="submit">
{{#if data.token}}
<button class="button red delete"><i class="icon-trash"></i><span>{{_ "Delete"}}</span></button>
{{/if}}
<button class="button save"><i class="icon-send"></i><span>{{_ "Save_changes"}}</span></button>
</div>
</div>
{{else}}
{{_ "Not_authorized"}}
{{/if}}
</div>
</template>

@ -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')

@ -0,0 +1,33 @@
<template name="oauthApps">
<div class="permissions-manager">
{{#if hasPermission}}
<a href="{{pathFor "admin-oauth-app"}}" class="button primary new-role">{{_ "New_Application"}}</a>
<div class="rocket-form">
<div class="section">
<div class="admin-integrations-new-panel">
{{#each applications}}
<a href="{{pathFor "admin-oauth-app" id=_id}}">
<div class="admin-integrations-new-item">
<div class="admin-integrations-new-item-body">
<div class="admin-integrations-new-item-title">
{{name}}
</div>
<div class="admin-integrations-new-item-description">
{{{_ "Created_at_s_by_s" (dateFormated _createdAt) _createdBy.username}}}
</div>
</div>
<i class="icon-angle-right"></i>
</div>
</a>
{{else}}
<h1>{{_ "There_are_no_applications"}}</h1>
{{/each}}
</div>
</div>
</div>
{{else}}
{{_ "Not_authorized"}}
{{/if}}
</div>
</template>

@ -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

@ -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

@ -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)

@ -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

@ -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()

@ -1,2 +0,0 @@
RocketChat.theme.addPackageAsset ->
return Assets.getText 'client/stylesheets/oauth2.less'

@ -0,0 +1,2 @@
RocketChat.theme.addPackageAsset ->
return Assets.getText 'oauth/client/stylesheets/oauth2.less'

@ -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');
});

Loading…
Cancel
Save