Improved oauth admin area.
This commit is contained in:
parent
faafe0cc60
commit
48e084df3d
7 changed files with 119 additions and 19 deletions
|
@ -76,14 +76,15 @@ class App.ControllerTable extends App.Controller
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
console.log('checkboxClick', e.target)
|
console.log('checkboxClick', e.target)
|
||||||
|
|
||||||
callbackHeader = (header) ->
|
callbackHeader = (headers) ->
|
||||||
console.log('current header is', header)
|
console.log('current header is', headers)
|
||||||
# add new header item
|
# add new header item
|
||||||
attribute =
|
attribute =
|
||||||
name: 'some name'
|
name: 'some name'
|
||||||
display: 'Some Name'
|
display: 'Some Name'
|
||||||
header.push attribute
|
headers.push attribute
|
||||||
console.log('new header is', header)
|
console.log('new header is', headers)
|
||||||
|
headers
|
||||||
|
|
||||||
callbackAttributes = (value, object, attribute, header, refObject) ->
|
callbackAttributes = (value, object, attribute, header, refObject) ->
|
||||||
console.log('data of item col', value, object, attribute, header, refObject)
|
console.log('data of item col', value, object, attribute, header, refObject)
|
||||||
|
|
|
@ -34,6 +34,26 @@ class Index extends App.ControllerSubContent
|
||||||
App.Setting.unsubscribe(@subscribeApplicationId)
|
App.Setting.unsubscribe(@subscribeApplicationId)
|
||||||
|
|
||||||
table = =>
|
table = =>
|
||||||
|
|
||||||
|
callbackHeader = (headers) ->
|
||||||
|
attribute =
|
||||||
|
name: 'view'
|
||||||
|
display: 'View'
|
||||||
|
headers.splice(3, 0, attribute)
|
||||||
|
attribute =
|
||||||
|
name: 'token'
|
||||||
|
display: 'Token'
|
||||||
|
headers.splice(4, 0, attribute)
|
||||||
|
headers
|
||||||
|
|
||||||
|
callbackViewAttributes = (value, object, attribute, header, refObject) ->
|
||||||
|
value = 'X'
|
||||||
|
value
|
||||||
|
|
||||||
|
callbackTokenAttributes = (value, object, attribute, header, refObject) ->
|
||||||
|
value = 'X'
|
||||||
|
value
|
||||||
|
|
||||||
new App.ControllerTable(
|
new App.ControllerTable(
|
||||||
el: @$('.js-appList')
|
el: @$('.js-appList')
|
||||||
model: App.Application
|
model: App.Application
|
||||||
|
@ -42,12 +62,19 @@ class Index extends App.ControllerSubContent
|
||||||
bindRow:
|
bindRow:
|
||||||
events:
|
events:
|
||||||
'click': @appEdit
|
'click': @appEdit
|
||||||
|
bindCol:
|
||||||
|
view:
|
||||||
|
events:
|
||||||
|
'click': @appView
|
||||||
|
token:
|
||||||
|
events:
|
||||||
|
'click': @appToken
|
||||||
|
callbackHeader: [callbackHeader]
|
||||||
|
callbackAttributes:
|
||||||
|
view: [callbackViewAttributes]
|
||||||
|
token: [callbackTokenAttributes]
|
||||||
)
|
)
|
||||||
table()
|
table()
|
||||||
#App.Application.fetchFull(
|
|
||||||
# table
|
|
||||||
# clear: true
|
|
||||||
#)
|
|
||||||
@subscribeApplicationId = App.Application.subscribe(table, initFetch: true, clear: true)
|
@subscribeApplicationId = App.Application.subscribe(table, initFetch: true, clear: true)
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +109,18 @@ class Index extends App.ControllerSubContent
|
||||||
value = @PasswordAccess.prop('checked')
|
value = @PasswordAccess.prop('checked')
|
||||||
App.Setting.set('api_password_access', value)
|
App.Setting.set('api_password_access', value)
|
||||||
|
|
||||||
|
appToken: (id, e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
new ViewAppTokenModal(
|
||||||
|
app: App.Application.find(id)
|
||||||
|
)
|
||||||
|
|
||||||
|
appView: (id, e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
new ViewAppModal(
|
||||||
|
app: App.Application.find(id)
|
||||||
|
)
|
||||||
|
|
||||||
appNew: (e) ->
|
appNew: (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
new App.ControllerGenericNew(
|
new App.ControllerGenericNew(
|
||||||
|
@ -107,4 +146,51 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class ViewAppModal extends App.ControllerModal
|
||||||
|
headPrefix: 'App'
|
||||||
|
buttonSubmit: false
|
||||||
|
buttonCancel: true
|
||||||
|
shown: true
|
||||||
|
small: true
|
||||||
|
events:
|
||||||
|
'click .js-select': 'selectAll'
|
||||||
|
|
||||||
|
constructor: (params) ->
|
||||||
|
@head = params.app.name
|
||||||
|
super
|
||||||
|
|
||||||
|
content: ->
|
||||||
|
"AppID: <input class=\"js-select\" type=\"text\" value=\"#{@app.uid}\">
|
||||||
|
<br>
|
||||||
|
Secret: <input class=\"js-select\" type=\"text\" value=\"#{@app.secret}\">"
|
||||||
|
|
||||||
|
class ViewAppTokenModal extends App.ControllerModal
|
||||||
|
headPrefix: 'Generate Token'
|
||||||
|
buttonSubmit: 'Generate Token'
|
||||||
|
buttonCancel: true
|
||||||
|
shown: true
|
||||||
|
small: true
|
||||||
|
events:
|
||||||
|
'click .js-select': 'selectAll'
|
||||||
|
|
||||||
|
constructor: (params) ->
|
||||||
|
@head = params.app.name
|
||||||
|
super
|
||||||
|
|
||||||
|
content: ->
|
||||||
|
"#{App.i18n.translateContent('Generate Access Token for |%s|', App.Session.get().displayNameLong())}"
|
||||||
|
|
||||||
|
onSubmit: =>
|
||||||
|
@ajax(
|
||||||
|
id: 'application_token'
|
||||||
|
type: 'POST'
|
||||||
|
url: "#{@apiPath}/applications/token"
|
||||||
|
processData: true
|
||||||
|
data: JSON.stringify(id: @app.id)
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
@contentInline = "#{App.i18n.translateContent('New Access Token is')}: <input class=\"js-select\" type=\"text\" value=\"#{data.token}\">"
|
||||||
|
@update()
|
||||||
|
@$('.js-submit').remove()
|
||||||
|
)
|
||||||
|
|
||||||
App.Config.set('API', { prio: 1200, name: 'API', parent: '#system', target: '#system/api', controller: Index, permission: ['admin.api'] }, 'NavBarAdmin')
|
App.Config.set('API', { prio: 1200, name: 'API', parent: '#system', target: '#system/api', controller: Index, permission: ['admin.api'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
class App.Application extends App.Model
|
class App.Application extends App.Model
|
||||||
@configure 'Application', 'name', 'redirect_uri', 'uid', 'secret'
|
@configure 'Application', 'name', 'redirect_uri'
|
||||||
@extend Spine.Model.Ajax
|
@extend Spine.Model.Ajax
|
||||||
@url: @apiPath + '/applications'
|
@url: @apiPath + '/applications'
|
||||||
|
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
|
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
|
||||||
{ name: 'redirect_uri', display: 'Redirect URI', tag: 'textarea', limit: 250, null: false, note: 'Use one line per URI' },
|
{ name: 'redirect_uri', display: 'Callback URL', tag: 'textarea', limit: 250, null: false, note: 'Use one line per URI' },
|
||||||
{ name: 'uid', display: 'Application ID', tag: 'input', type: 'text', null: true, readonly: 1 },
|
{ name: 'clients', display: 'Clients', tag: 'input', readonly: 1 },
|
||||||
{ name: 'secret', display: 'Application secret', tag: 'input', type: 'text', null: true },
|
|
||||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||||
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
||||||
]
|
]
|
||||||
@configure_overview = [
|
@configure_overview = [
|
||||||
'name', 'uid'
|
'name', 'redirect_uri', 'clients'
|
||||||
]
|
]
|
||||||
@configure_delete = true
|
@configure_delete = true
|
||||||
|
|
|
@ -51,6 +51,7 @@ curl -u <%= @S('email') %>:some_password <%= @C('http_type') %>://<%= @C('fqdn')
|
||||||
|
|
||||||
<button class="btn js-appNew"><%- @T('New Application') %></button>
|
<button class="btn js-appNew"><%- @T('New Application') %></button>
|
||||||
|
|
||||||
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -308,6 +308,10 @@ class ApplicationController < ActionController::Base
|
||||||
logger.debug "oauth2 token auth check '#{token}'"
|
logger.debug "oauth2 token auth check '#{token}'"
|
||||||
access_token = Doorkeeper::AccessToken.by_token(token)
|
access_token = Doorkeeper::AccessToken.by_token(token)
|
||||||
|
|
||||||
|
if !access_token
|
||||||
|
raise Exceptions::NotAuthorized, 'Invalid token!'
|
||||||
|
end
|
||||||
|
|
||||||
# check expire
|
# check expire
|
||||||
if access_token.expires_in && (access_token.created_at + access_token.expires_in) < Time.zone.now
|
if access_token.expires_in && (access_token.created_at + access_token.expires_in) < Time.zone.now
|
||||||
raise Exceptions::NotAuthorized, 'OAuth2 token is expired!'
|
raise Exceptions::NotAuthorized, 'OAuth2 token is expired!'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class ApplicationsController < ApplicationController
|
class ApplicationsController < ApplicationController
|
||||||
before_action { authentication_check(permission: 'admin.api') }
|
before_action { authentication_check(permission: 'admin.api') }
|
||||||
|
@ -13,7 +13,9 @@ class ApplicationsController < ApplicationController
|
||||||
if !assets[:Application]
|
if !assets[:Application]
|
||||||
assets[:Application] = {}
|
assets[:Application] = {}
|
||||||
end
|
end
|
||||||
assets[:Application][item.id] = item.attributes
|
application = item.attributes
|
||||||
|
application[:clients] = Doorkeeper::AccessToken.where(application_id: item.id).count
|
||||||
|
assets[:Application][item.id] = application
|
||||||
}
|
}
|
||||||
render json: {
|
render json: {
|
||||||
record_ids: item_ids,
|
record_ids: item_ids,
|
||||||
|
@ -25,6 +27,11 @@ class ApplicationsController < ApplicationController
|
||||||
render json: all, status: :ok
|
render json: all, status: :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def token
|
||||||
|
access_token = Doorkeeper::AccessToken.create!(application_id: params[:id], resource_owner_id: current_user.id)
|
||||||
|
render json: { token: access_token.token }, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
application = Doorkeeper::Application.find(params[:id])
|
application = Doorkeeper::Application.find(params[:id])
|
||||||
render json: application, status: :ok
|
render json: application, status: :ok
|
||||||
|
@ -59,6 +66,7 @@ class ApplicationsController < ApplicationController
|
||||||
params_data.delete('uid')
|
params_data.delete('uid')
|
||||||
params_data.delete('secret')
|
params_data.delete('secret')
|
||||||
params_data.delete('created_at')
|
params_data.delete('created_at')
|
||||||
|
params_data.delete('updated_at')
|
||||||
params_data
|
params_data
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,7 @@ Zammad::Application.routes.draw do
|
||||||
match api_path + '/applications/:id', to: 'applications#show', via: :get
|
match api_path + '/applications/:id', to: 'applications#show', via: :get
|
||||||
match api_path + '/applications', to: 'applications#create', via: :post
|
match api_path + '/applications', to: 'applications#create', via: :post
|
||||||
match api_path + '/applications/:id', to: 'applications#update', via: :put
|
match api_path + '/applications/:id', to: 'applications#update', via: :put
|
||||||
|
match api_path + '/applications/token', to: 'applications#token', via: :post
|
||||||
|
|
||||||
# oauth2 provider routes
|
# oauth2 provider routes
|
||||||
use_doorkeeper do
|
use_doorkeeper do
|
Loading…
Reference in a new issue