Added permission based/permission check setting api.

This commit is contained in:
Martin Edenhofer 2016-08-26 12:06:27 +02:00
parent 00f9c47839
commit 6bd5ae6471
7 changed files with 987 additions and 68 deletions

View file

@ -5,29 +5,38 @@ class SettingsController < ApplicationController
# GET /settings # GET /settings
def index def index
model_index_render(Setting, params) list = []
Setting.all.each { |setting|
next if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission])
list.push setting
}
render json: list, status: :ok
end end
# GET /settings/1 # GET /settings/1
def show def show
check_access('read')
model_show_render(Setting, params) model_show_render(Setting, params)
end end
# POST /settings # POST /settings
def create def create
model_create_render(Setting, params) raise Exceptions::NotAuthorized, 'Not authorized (feature not possible)'
end end
# PUT /settings/1 # PUT /settings/1
def update def update
check_access check_access('write')
model_update_render(Setting, params) clean_params = keep_certain_attributes
model_update_render(Setting, clean_params)
end end
# PUT /settings/image/:id # PUT /settings/image/:id
def update_image def update_image
check_access('write')
clean_params = keep_certain_attributes
if !params[:logo] if !clean_params[:logo]
render json: { render json: {
result: 'invalid', result: 'invalid',
message: 'Need logo param', message: 'Need logo param',
@ -36,7 +45,7 @@ class SettingsController < ApplicationController
end end
# validate image # validate image
if params[:logo] !~ /^data:image/i if clean_params[:logo] !~ /^data:image/i
render json: { render json: {
result: 'invalid', result: 'invalid',
message: 'Invalid payload, need data:image in logo param', message: 'Invalid payload, need data:image in logo param',
@ -45,7 +54,7 @@ class SettingsController < ApplicationController
end end
# process image # process image
file = StaticAssets.data_url_attributes(params[:logo]) file = StaticAssets.data_url_attributes(clean_params[:logo])
if !file[:content] || !file[:mime_type] if !file[:content] || !file[:mime_type]
render json: { render json: {
result: 'invalid', result: 'invalid',
@ -58,7 +67,7 @@ class SettingsController < ApplicationController
StaticAssets.store_raw(file[:content], file[:mime_type]) StaticAssets.store_raw(file[:content], file[:mime_type])
# store resized image 1:1 # store resized image 1:1
setting = Setting.find_by(name: 'product_logo') setting = Setting.lookup(name: 'product_logo')
if params[:logo_resize] && params[:logo_resize] =~ /^data:image/i if params[:logo_resize] && params[:logo_resize] =~ /^data:image/i
# data:image/png;base64 # data:image/png;base64
@ -66,7 +75,7 @@ class SettingsController < ApplicationController
# store image 1:1 # store image 1:1
setting.state = StaticAssets.store(file[:content], file[:mime_type]) setting.state = StaticAssets.store(file[:content], file[:mime_type])
setting.save setting.save!
end end
render json: { render json: {
@ -77,16 +86,36 @@ class SettingsController < ApplicationController
# DELETE /settings/1 # DELETE /settings/1
def destroy def destroy
check_access raise Exceptions::NotAuthorized, 'Not authorized (feature not possible)'
model_destory_render(Setting, params)
end end
private private
def check_access def keep_certain_attributes
return true if !Setting.get('system_online_service')
setting = Setting.find(params[:id]) setting = Setting.find(params[:id])
return true if setting.preferences && !setting.preferences[:online_service_disable] [:name, :area, :state_initial, :frontend, :options].each { |key|
raise Exceptions::NotAuthorized params.delete(key)
}
[:online_service_disable, :permission, :render].each { |key|
params[:preferences].delete(key)
}
params[:preferences].merge!(setting.preferences)
params
end
def check_access(type)
setting = Setting.lookup(id: params[:id])
if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission])
raise Exceptions::NotAuthorized, "Not authorized (required #{setting.preferences[:permission].inspect})"
end
if type == 'write'
return true if !Setting.get('system_online_service')
if setting.preferences && setting.preferences[:online_service_disable]
raise Exceptions::NotAuthorized, 'Not authorized (service disabled)'
end
end
true
end end
end end

View file

@ -350,6 +350,8 @@ true or false for permission
user.permissions?('permission') # access to all sub keys user.permissions?('permission') # access to all sub keys
user.permissions?('permission.*') # access if one sub key access exists
returns returns
true|false true|false
@ -368,8 +370,16 @@ returns
cache = Cache.get(cache_key) cache = Cache.get(cache_key)
return cache if cache return cache if cache
end end
list = []
if local_key =~ /\.\*$/
local_key.sub!('.*', '.%')
permissions = Object.const_get('Permission').with_parents(local_key) permissions = Object.const_get('Permission').with_parents(local_key)
Object.const_get('Permission').joins(:roles).where('roles.id IN (?) AND permissions.name IN (?)', role_ids, permissions).each { |permission| list = Object.const_get('Permission').joins(:roles).where('roles.id IN (?) AND (permissions.name IN (?) OR permissions.name LIKE ?)', role_ids, permissions, local_key)
else
permissions = Object.const_get('Permission').with_parents(local_key)
list = Object.const_get('Permission').joins(:roles).where('roles.id IN (?) AND permissions.name IN (?)', role_ids, permissions)
end
list.each { |permission|
next if permission.preferences[:selectable] == false next if permission.preferences[:selectable] == false
Cache.write(key, true, expires_in: 20.seconds) Cache.write(key, true, expires_in: 20.seconds)
return true return true

View file

@ -0,0 +1,462 @@
class UpdateSettingPermission < ActiveRecord::Migration
def up
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
updates = [
{
name: 'maintenance_mode',
preferences: {
permission: ['admin.maintenance']
},
},
{
name: 'maintenance_login',
preferences: {
permission: ['admin.maintenance']
},
},
{
name: 'maintenance_login_message',
preferences: {
permission: ['admin.maintenance']
},
},
{
name: 'product_name',
preferences: {
permission: ['admin.branding']
},
},
{
name: 'product_logo',
preferences: {
permission: ['admin.branding']
},
},
{
name: 'system_id',
preferences: {
permission: ['admin.system']
},
},
{
name: 'fqdn',
preferences: {
permission: ['admin.system']
},
},
{
name: 'http_type',
preferences: {
permission: ['admin.system']
},
},
{
name: 'storage',
preferences: {
permission: ['admin.system']
},
},
{
name: 'image_backend',
preferences: {
permission: ['admin.system']
},
},
{
name: 'geo_ip_backend',
preferences: {
permission: ['admin.system']
},
},
{
name: 'geo_location_backend',
preferences: {
permission: ['admin.system']
},
},
{
name: 'geo_calendar_backend',
preferences: {
permission: ['admin.system']
},
},
{
name: 'ui_send_client_stats',
preferences: {
permission: ['admin.system']
},
},
{
name: 'ui_client_storage',
preferences: {
permission: ['admin.system']
},
},
{
name: 'user_create_account',
preferences: {
permission: ['admin.security']
},
},
{
name: 'user_lost_password',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_ldap',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_twitter',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_twitter_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_facebook',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_facebook_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_google_oauth2',
preferences: {
permission: ['admin.maintenance']
},
},
{
name: 'maintenance_mode',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_google_oauth2_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_linkedin',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_linkedin_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_github',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_github_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_gitlab',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_gitlab_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_oauth2',
preferences: {
permission: ['admin.security']
},
},
{
name: 'auth_oauth2_credentials',
preferences: {
permission: ['admin.security']
},
},
{
name: 'password_min_size',
preferences: {
permission: ['admin.security']
},
},
{
name: 'password_min_2_lower_2_upper_characters',
preferences: {
permission: ['admin.security']
},
},
{
name: 'password_need_digit',
preferences: {
permission: ['admin.security']
},
},
{
name: 'password_max_login_failed',
preferences: {
permission: ['admin.security']
},
},
{
name: 'ticket_hook',
preferences: {
permission: ['admin.ticket']
},
},
{
name: 'ticket_hook_divider',
preferences: {
permission: ['admin.ticket']
},
},
{
name: 'ticket_hook_position',
preferences: {
permission: ['admin.ticket']
},
},
{
name: 'ticket_number',
preferences: {
permission: ['admin.ticket']
},
},
{
name: 'ticket_number_increment',
preferences: {
permission: ['admin.ticket']
},
},
{
name: 'ticket_number_date',
preferences: {
permission: ['admin.ticket']
},
},
{
name: 'customer_ticket_create',
preferences: {
permission: ['admin.channel_web']
},
},
{
name: 'customer_ticket_create_group_ids',
preferences: {
permission: ['admin.channel_web']
},
},
{
name: 'customer_ticket_view',
preferences: {
permission: ['admin.channel_web']
},
},
{
name: 'form_ticket_create',
preferences: {
permission: ['admin.channel_formular']
},
},
{
name: 'ticket_subject_size',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'ticket_subject_re',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'ticket_define_email_from',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'ticket_define_email_from_seperator',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'postmaster_max_size',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'postmaster_follow_up_search_in',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'notification_sender',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'send_no_auto_response_reg_exp',
preferences: {
permission: ['admin.channel_email']
},
},
{
name: 'api_token_access',
preferences: {
permission: ['admin.api']
},
},
{
name: 'api_password_access',
preferences: {
permission: ['admin.api']
},
},
{
name: 'chat',
preferences: {
permission: ['admin.channel_chat']
},
},
{
name: 'chat_agent_idle_timeout',
preferences: {
permission: ['admin.channel_chat']
},
},
{
name: 'tag_new',
preferences: {
permission: ['admin.tag']
},
},
{
name: 'icinga_integration',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'icinga_sender',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'icinga_auto_close',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'icinga_auto_close_state_id',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'nagios_integration',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'nagios_sender',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'nagios_auto_close',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'nagios_auto_close_state_id',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'slack_integration',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'slack_config',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'sipgate_integration',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'sipgate_config',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'clearbit_integration',
preferences: {
permission: ['admin.integration']
},
},
{
name: 'clearbit_config',
preferences: {
permission: ['admin.integration']
},
},
]
updates.each { |item|
setting = Setting.find_by(name: item[:name])
item[:preferences].each { |key, value|
setting.preferences[key] = value
}
setting.save!
}
end
end

View file

@ -33,7 +33,9 @@ Setting.create_if_not_exists(
description: 'Enable or disable the maintenance mode of Zammad. If enabled, all non-administrators get logged out and only administrators can start a new session.', description: 'Enable or disable the maintenance mode of Zammad. If enabled, all non-administrators get logged out and only administrators can start a new session.',
options: {}, options: {},
state: false, state: false,
preferences: {}, preferences: {
permission: ['admin.maintenance'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -43,7 +45,9 @@ Setting.create_if_not_exists(
description: 'Put a message on the login page. To change it, click on the text area below and change it inline.', description: 'Put a message on the login page. To change it, click on the text area below and change it inline.',
options: {}, options: {},
state: false, state: false,
preferences: {}, preferences: {
permission: ['admin.maintenance'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -53,7 +57,9 @@ Setting.create_if_not_exists(
description: 'Message for login page.', description: 'Message for login page.',
options: {}, options: {},
state: 'Something about to share. Click here to change.', state: 'Something about to share. Click here to change.',
preferences: {}, preferences: {
permission: ['admin.maintenance'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -91,7 +97,13 @@ Setting.create_if_not_exists(
}, },
], ],
}, },
preferences: { render: true, session_check: true, prio: 1, placeholder: true }, preferences: {
render: true,
session_check: true,
prio: 1,
placeholder: true,
permission: ['admin.branding'],
},
state: 'Zammad Helpdesk', state: 'Zammad Helpdesk',
frontend: true frontend: true
) )
@ -113,6 +125,7 @@ Setting.create_if_not_exists(
preferences: { preferences: {
prio: 3, prio: 3,
controller: 'SettingsAreaLogo', controller: 'SettingsAreaLogo',
permission: ['admin.branding'],
}, },
state: 'logo.svg', state: 'logo.svg',
frontend: true frontend: true
@ -133,7 +146,11 @@ Setting.create_if_not_exists(
], ],
}, },
state: '', state: '',
preferences: { prio: 2, placeholder: true }, preferences: {
prio: 2,
placeholder: true,
permission: ['admin.branding'],
},
frontend: true frontend: true
) )
options = {} options = {}
@ -162,6 +179,7 @@ Setting.create_if_not_exists(
online_service_disable: true, online_service_disable: true,
placeholder: true, placeholder: true,
authentication: true, authentication: true,
permission: ['admin.system'],
}, },
frontend: true frontend: true
) )
@ -181,7 +199,11 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'zammad.example.com', state: 'zammad.example.com',
preferences: { online_service_disable: true, placeholder: true }, preferences: {
online_service_disable: true,
placeholder: true,
permission: ['admin.system'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -223,7 +245,11 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'http', state: 'http',
preferences: { online_service_disable: true, placeholder: true }, preferences: {
online_service_disable: true,
placeholder: true,
permission: ['admin.system'],
},
frontend: true frontend: true
) )
@ -247,7 +273,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'DB', state: 'DB',
preferences: { online_service_disable: true }, preferences: {
online_service_disable: true,
permission: ['admin.system'],
},
frontend: false frontend: false
) )
@ -271,7 +300,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'Service::Image::Zammad', state: 'Service::Image::Zammad',
preferences: { prio: 1 }, preferences: {
prio: 1,
permission: ['admin.system'],
},
frontend: false frontend: false
) )
@ -295,7 +327,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'Service::GeoIp::Zammad', state: 'Service::GeoIp::Zammad',
preferences: { prio: 2 }, preferences: {
prio: 2,
permission: ['admin.system'],
},
frontend: false frontend: false
) )
@ -319,7 +354,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'Service::GeoLocation::Gmaps', state: 'Service::GeoLocation::Gmaps',
preferences: { prio: 3 }, preferences: {
prio: 3,
permission: ['admin.system'],
},
frontend: false frontend: false
) )
@ -343,7 +381,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'Service::GeoCalendar::Zammad', state: 'Service::GeoCalendar::Zammad',
preferences: { prio: 2 }, preferences: {
prio: 2,
permission: ['admin.system'],
},
frontend: false frontend: false
) )
@ -367,7 +408,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: true, state: true,
preferences: { prio: 1 }, preferences: {
prio: 1,
permission: ['admin.system'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -390,7 +434,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: false, state: false,
preferences: { prio: 2 }, preferences: {
prio: 2,
permission: ['admin.system'],
},
frontend: true frontend: true
) )
@ -414,6 +461,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: true, state: true,
preferences: {
permission: ['admin.security'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -436,6 +486,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: true, state: true,
preferences: {
permission: ['admin.security'],
},
frontend: true frontend: true
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -445,7 +498,8 @@ Setting.create_if_not_exists(
description: 'Enables user authentication via %s.', description: 'Enables user authentication via %s.',
preferences: { preferences: {
title_i18n: ['LDAP'], title_i18n: ['LDAP'],
description_i18n: ['LDAP'] description_i18n: ['LDAP'],
permission: ['admin.security'],
}, },
state: { state: {
adapter: 'Auth::Ldap', adapter: 'Auth::Ldap',
@ -490,7 +544,8 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_twitter_credentials'], sub: ['auth_twitter_credentials'],
title_i18n: ['Twitter'], title_i18n: ['Twitter'],
description_i18n: ['Twitter', 'Twitter Developer Site', 'https://dev.twitter.com/apps'] description_i18n: ['Twitter', 'Twitter Developer Site', 'https://dev.twitter.com/apps'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -517,6 +572,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -542,7 +600,8 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_facebook_credentials'], sub: ['auth_facebook_credentials'],
title_i18n: ['Facebook'], title_i18n: ['Facebook'],
description_i18n: ['Facebook', 'Facebook Developer Site', 'https://developers.facebook.com/apps/'] description_i18n: ['Facebook', 'Facebook Developer Site', 'https://developers.facebook.com/apps/'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -570,6 +629,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -596,7 +658,8 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_google_oauth2_credentials'], sub: ['auth_google_oauth2_credentials'],
title_i18n: ['Google'], title_i18n: ['Google'],
description_i18n: ['Google', 'Google API Console Site', 'https://console.developers.google.com/apis/credentials'] description_i18n: ['Google', 'Google API Console Site', 'https://console.developers.google.com/apis/credentials'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -623,6 +686,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -649,7 +715,8 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_linkedin_credentials'], sub: ['auth_linkedin_credentials'],
title_i18n: ['LinkedIn'], title_i18n: ['LinkedIn'],
description_i18n: ['LinkedIn', 'Linkedin Developer Site', 'https://www.linkedin.com/developer/apps'] description_i18n: ['LinkedIn', 'Linkedin Developer Site', 'https://www.linkedin.com/developer/apps'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -676,6 +743,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -702,7 +772,8 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_github_credentials'], sub: ['auth_github_credentials'],
title_i18n: ['Github'], title_i18n: ['Github'],
description_i18n: ['Github', 'Github OAuth Applications', 'https://github.com/settings/applications'] description_i18n: ['Github', 'Github OAuth Applications', 'https://github.com/settings/applications'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -729,6 +800,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -755,7 +829,8 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_gitlab_credentials'], sub: ['auth_gitlab_credentials'],
title_i18n: ['Gitlab'], title_i18n: ['Gitlab'],
description_i18n: ['Gitlab', 'Gitlab Applications', 'https://your-gitlab-host/admin/applications'] description_i18n: ['Gitlab', 'Gitlab Applications', 'https://your-gitlab-host/admin/applications'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -789,6 +864,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -815,6 +893,7 @@ Setting.create_if_not_exists(
controller: 'SettingsAreaSwitch', controller: 'SettingsAreaSwitch',
sub: ['auth_oauth2_credentials'], sub: ['auth_oauth2_credentials'],
title_i18n: ['Generic OAuth2'], title_i18n: ['Generic OAuth2'],
permission: ['admin.security'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -869,6 +948,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: {}, state: {},
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -907,6 +989,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 6, state: 6,
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -929,6 +1014,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 0, state: 0,
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -951,6 +1039,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 1, state: 1,
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -987,6 +1078,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 10, state: 10,
preferences: {
permission: ['admin.security'],
},
frontend: false frontend: false
) )
@ -1009,6 +1103,7 @@ Setting.create_if_not_exists(
render: true, render: true,
placeholder: true, placeholder: true,
authentication: true, authentication: true,
permission: ['admin.ticket'],
}, },
state: 'Ticket#', state: 'Ticket#',
frontend: true frontend: true
@ -1029,6 +1124,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: '', state: '',
preferences: {
permission: ['admin.ticket'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -1055,6 +1153,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'right', state: 'right',
preferences: {
permission: ['admin.ticket'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -1081,6 +1182,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'Ticket::Number::Increment', state: 'Ticket::Number::Increment',
preferences: {
permission: ['admin.ticket'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -1134,6 +1238,9 @@ Setting.create_if_not_exists(
checksum: false, checksum: false,
min_size: 5, min_size: 5,
}, },
preferences: {
permission: ['admin.ticket'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -1158,6 +1265,9 @@ Setting.create_if_not_exists(
state: { state: {
checksum: false, checksum: false,
}, },
preferences: {
permission: ['admin.ticket'],
},
frontend: false frontend: false
) )
@ -1183,6 +1293,7 @@ Setting.create_if_not_exists(
state: true, state: true,
preferences: { preferences: {
authentication: true, authentication: true,
permission: ['admin.channel_web'],
}, },
frontend: true frontend: true
) )
@ -1208,6 +1319,7 @@ Setting.create_if_not_exists(
state: '', state: '',
preferences: { preferences: {
authentication: true, authentication: true,
permission: ['admin.channel_web'],
}, },
frontend: true frontend: true
) )
@ -1234,6 +1346,7 @@ Setting.create_if_not_exists(
state: true, state: true,
preferences: { preferences: {
authentication: true, authentication: true,
permission: ['admin.channel_web'],
}, },
frontend: true frontend: true
) )
@ -1258,6 +1371,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: false, state: false,
preferences: {
permission: ['admin.channel_formular'],
},
frontend: false, frontend: false,
) )
@ -1277,6 +1393,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: '110', state: '110',
preferences: {
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -1295,6 +1414,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'RE', state: 'RE',
preferences: {
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1318,6 +1440,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'AgentNameSystemAddressName', state: 'AgentNameSystemAddressName',
preferences: {
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1337,6 +1462,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'via', state: 'via',
preferences: {
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1383,7 +1511,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 10, state: 10,
preferences: { online_service_disable: true }, preferences: {
online_service_disable: true,
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1408,6 +1539,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: [], state: [],
preferences: {
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1427,7 +1561,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'Notification Master <noreply@#{config.fqdn}>', state: 'Notification Master <noreply@#{config.fqdn}>',
preferences: { online_service_disable: true }, preferences: {
online_service_disable: true,
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1447,7 +1584,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: '(mailer-daemon|postmaster|abuse|root|noreply|noreply.+?|no-reply|no-reply.+?)@.+?\..+?', state: '(mailer-daemon|postmaster|abuse|root|noreply|noreply.+?|no-reply|no-reply.+?)@.+?\..+?',
preferences: { online_service_disable: true }, preferences: {
online_service_disable: true,
permission: ['admin.channel_email'],
},
frontend: false frontend: false
) )
@ -1471,6 +1611,9 @@ Setting.create_or_update(
], ],
}, },
state: true, state: true,
preferences: {
permission: ['admin.api'],
},
frontend: false frontend: false
) )
Setting.create_or_update( Setting.create_or_update(
@ -1493,6 +1636,9 @@ Setting.create_or_update(
], ],
}, },
state: true, state: true,
preferences: {
permission: ['admin.api'],
},
frontend: false frontend: false
) )
@ -1516,7 +1662,8 @@ Setting.create_if_not_exists(
], ],
}, },
preferences: { preferences: {
trigger: ['menu:render', 'chat:rerender'] trigger: ['menu:render', 'chat:rerender'],
permission: ['admin.channel_chat'],
}, },
state: false, state: false,
frontend: true frontend: true
@ -1538,6 +1685,9 @@ Setting.create_if_not_exists(
], ],
}, },
state: '120', state: '120',
preferences: {
permission: ['admin.channel_chat'],
},
frontend: true frontend: true
) )
@ -1825,6 +1975,7 @@ Setting.create_if_not_exists(
}, },
preferences: { preferences: {
authentication: true, authentication: true,
permission: ['admin.tag'],
}, },
state: true, state: true,
frontend: true frontend: true
@ -1976,7 +2127,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: false, state: false,
preferences: { prio: 1 }, preferences: {
prio: 1,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -1996,8 +2150,11 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'icinga@monitoring.example.com', state: 'icinga@monitoring.example.com',
preferences: {
prio: 2,
permission: ['admin.integration'],
},
frontend: false, frontend: false,
preferences: { prio: 2 },
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: 'Auto close', title: 'Auto close',
@ -2019,7 +2176,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: true, state: true,
preferences: { prio: 3 }, preferences: {
prio: 3,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2039,7 +2199,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 4, state: 4,
preferences: { prio: 4 }, preferences: {
prio: 4,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2062,7 +2225,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: false, state: false,
preferences: { prio: 1 }, preferences: {
prio: 1,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2082,8 +2248,11 @@ Setting.create_if_not_exists(
], ],
}, },
state: 'nagios@monitoring.example.com', state: 'nagios@monitoring.example.com',
preferences: {
prio: 2,
permission: ['admin.integration'],
},
frontend: false, frontend: false,
preferences: { prio: 2 },
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: 'Auto close', title: 'Auto close',
@ -2105,7 +2274,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: true, state: true,
preferences: { prio: 3 }, preferences: {
prio: 3,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2125,7 +2297,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: 4, state: 4,
preferences: { prio: 4 }, preferences: {
prio: 4,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2184,7 +2359,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: false, state: false,
preferences: { prio: 1 }, preferences: {
prio: 1,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2196,8 +2374,11 @@ Setting.create_if_not_exists(
state: { state: {
items: [] items: []
}, },
preferences: {
prio: 2,
permission: ['admin.integration'],
},
frontend: false, frontend: false,
preferences: { prio: 2 },
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: 'sipgate.io integration', title: 'sipgate.io integration',
@ -2223,6 +2404,7 @@ Setting.create_if_not_exists(
prio: 1, prio: 1,
trigger: ['menu:render', 'cti:reload'], trigger: ['menu:render', 'cti:reload'],
authentication: true, authentication: true,
permission: ['admin.integration'],
}, },
frontend: true frontend: true
) )
@ -2233,8 +2415,11 @@ Setting.create_if_not_exists(
description: 'Define the sipgate.io config.', description: 'Define the sipgate.io config.',
options: {}, options: {},
state: {}, state: {},
preferences: {
prio: 2,
permission: ['admin.integration'],
},
frontend: false, frontend: false,
preferences: { prio: 2 },
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: 'Clearbit integration', title: 'Clearbit integration',
@ -2256,7 +2441,10 @@ Setting.create_if_not_exists(
], ],
}, },
state: false, state: false,
preferences: { prio: 1 }, preferences: {
prio: 1,
permission: ['admin.integration'],
},
frontend: false frontend: false
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
@ -2267,7 +2455,10 @@ Setting.create_if_not_exists(
options: {}, options: {},
state: {}, state: {},
frontend: false, frontend: false,
preferences: { prio: 2 }, preferences: {
prio: 2,
permission: ['admin.integration'],
},
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: 'Define transaction backend.', title: 'Define transaction backend.',
@ -2395,17 +2586,6 @@ Role.create_if_not_exists(
updated_by_id: 1, updated_by_id: 1,
created_by_id: 1 created_by_id: 1
) )
Role.create_if_not_exists(
id: 4,
name: 'Report',
note: 'Access the report area.',
preferences: {
not: ['Customer'],
},
default_at_signup: false,
created_by_id: 1,
updated_by_id: 1,
)
Permission.create_if_not_exists( Permission.create_if_not_exists(
name: 'admin', name: 'admin',

View file

@ -12,7 +12,7 @@ class SettingsControllerTest < ActionDispatch::IntegrationTest
groups = Group.all groups = Group.all
UserInfo.current_user_id = 1 UserInfo.current_user_id = 1
@admin = User.create_or_update( @admin_full = User.create_or_update(
login: 'setting-admin', login: 'setting-admin',
firstname: 'Setting', firstname: 'Setting',
lastname: 'Admin', lastname: 'Admin',
@ -23,6 +23,28 @@ class SettingsControllerTest < ActionDispatch::IntegrationTest
groups: groups, groups: groups,
) )
role_api = Role.create_or_update(
name: 'AdminApi',
note: 'To configure your api.',
preferences: {
not: ['Customer'],
},
default_at_signup: false,
updated_by_id: 1,
created_by_id: 1
)
role_api.permission_grand('admin.api')
@admin_api = User.create_or_update(
login: 'setting-admin-api',
firstname: 'Setting',
lastname: 'Admin Api',
email: 'setting-admin-api@example.com',
password: 'adminpw',
active: true,
roles: [role_api],
groups: groups,
)
# create agent # create agent
roles = Role.where(name: 'Agent') roles = Role.where(name: 'Agent')
@agent = User.create_or_update( @agent = User.create_or_update(
@ -58,6 +80,13 @@ class SettingsControllerTest < ActionDispatch::IntegrationTest
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
assert_equal(Hash, result.class) assert_equal(Hash, result.class)
assert_not(result['settings']) assert_not(result['settings'])
# show
setting = Setting.find_by(name: 'product_name')
get "/api/v1/settings/#{setting.id}", {}
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized', result['error'])
end end
test 'settings index with admin' do test 'settings index with admin' do
@ -70,6 +99,157 @@ class SettingsControllerTest < ActionDispatch::IntegrationTest
result = JSON.parse(@response.body) result = JSON.parse(@response.body)
assert_equal(Array, result.class) assert_equal(Array, result.class)
assert(result) assert(result)
hit_api = false
hit_product_name = false
result.each { |setting|
if setting['name'] == 'api_token_access'
hit_api = true
end
if setting['name'] == 'product_name'
hit_product_name = true
end
}
assert_equal(true, hit_api)
assert_equal(true, hit_product_name)
# show
setting = Setting.find_by(name: 'product_name')
get "/api/v1/settings/#{setting.id}", {}, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('product_name', result['name'])
setting = Setting.find_by(name: 'api_token_access')
get "/api/v1/settings/#{setting.id}", {}, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('api_token_access', result['name'])
# update
setting = Setting.find_by(name: 'product_name')
params = {
id: setting.id,
name: 'some_new_name',
preferences: {
permission: ['admin.branding', 'admin.some_new_permission'],
some_new_key: true,
}
}
put "/api/v1/settings/#{setting.id}", params.to_json, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('product_name', result['name'])
assert_equal(1, result['preferences']['permission'].length)
assert_equal('admin.branding', result['preferences']['permission'][0])
assert_equal(true, result['preferences']['some_new_key'])
# update
setting = Setting.find_by(name: 'api_token_access')
params = {
id: setting.id,
name: 'some_new_name',
preferences: {
permission: ['admin.branding', 'admin.some_new_permission'],
some_new_key: true,
}
}
put "/api/v1/settings/#{setting.id}", params.to_json, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('api_token_access', result['name'])
assert_equal(1, result['preferences']['permission'].length)
assert_equal('admin.api', result['preferences']['permission'][0])
assert_equal(true, result['preferences']['some_new_key'])
# delete
setting = Setting.find_by(name: 'product_name')
delete "/api/v1/settings/#{setting.id}", {}.to_json, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (feature not possible)', result['error'])
end
test 'settings index with admin-api' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('setting-admin-api@example.com', 'adminpw')
# index
get '/api/v1/settings', {}, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Array, result.class)
assert(result)
hit_api = false
hit_product_name = false
result.each { |setting|
if setting['name'] == 'api_token_access'
hit_api = true
end
if setting['name'] == 'product_name'
hit_product_name = true
end
}
assert_equal(true, hit_api)
assert_equal(false, hit_product_name)
# show
setting = Setting.find_by(name: 'product_name')
get "/api/v1/settings/#{setting.id}", {}, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (required ["admin.branding"])', result['error'])
setting = Setting.find_by(name: 'api_token_access')
get "/api/v1/settings/#{setting.id}", {}, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('api_token_access', result['name'])
# update
setting = Setting.find_by(name: 'product_name')
params = {
id: setting.id,
name: 'some_new_name',
preferences: {
permission: ['admin.branding', 'admin.some_new_permission'],
some_new_key: true,
}
}
put "/api/v1/settings/#{setting.id}", params.to_json, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (required ["admin.branding"])', result['error'])
# update
setting = Setting.find_by(name: 'api_token_access')
params = {
id: setting.id,
name: 'some_new_name',
preferences: {
permission: ['admin.branding', 'admin.some_new_permission'],
some_new_key: true,
}
}
put "/api/v1/settings/#{setting.id}", params.to_json, @headers.merge('Authorization' => credentials)
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('api_token_access', result['name'])
assert_equal(1, result['preferences']['permission'].length)
assert_equal('admin.api', result['preferences']['permission'][0])
assert_equal(true, result['preferences']['some_new_key'])
# delete
setting = Setting.find_by(name: 'product_name')
delete "/api/v1/settings/#{setting.id}", {}.to_json, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (feature not possible)', result['error'])
end end
test 'settings index with agent' do test 'settings index with agent' do
@ -83,6 +263,13 @@ class SettingsControllerTest < ActionDispatch::IntegrationTest
assert_equal(Hash, result.class) assert_equal(Hash, result.class)
assert_not(result['settings']) assert_not(result['settings'])
assert_equal('Not authorized (user)!', result['error']) assert_equal('Not authorized (user)!', result['error'])
# show
setting = Setting.find_by(name: 'product_name')
get "/api/v1/settings/#{setting.id}", {}, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (user)', result['error'])
end end
test 'settings index with customer' do test 'settings index with customer' do
@ -96,6 +283,20 @@ class SettingsControllerTest < ActionDispatch::IntegrationTest
assert_equal(Hash, result.class) assert_equal(Hash, result.class)
assert_not(result['settings']) assert_not(result['settings'])
assert_equal('Not authorized (user)!', result['error']) assert_equal('Not authorized (user)!', result['error'])
# show
setting = Setting.find_by(name: 'product_name')
get "/api/v1/settings/#{setting.id}", {}, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (user)', result['error'])
# delete
setting = Setting.find_by(name: 'product_name')
delete "/api/v1/settings/#{setting.id}", {}.to_json, @headers.merge('Authorization' => credentials)
assert_response(401)
result = JSON.parse(@response.body)
assert_equal('Not authorized (feature not possible)', result['error'])
end end
end end

View file

@ -46,7 +46,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
test 'check counts' do test 'check counts' do
assert_equal(143, User.count, 'users') assert_equal(143, User.count, 'users')
assert_equal(3, Group.count, 'groups') assert_equal(3, Group.count, 'groups')
assert_equal(4, Role.count, 'roles') assert_equal(3, Role.count, 'roles')
assert_equal(2, Organization.count, 'organizations') assert_equal(2, Organization.count, 'organizations')
assert_equal(143, Ticket.count, 'tickets') assert_equal(143, Ticket.count, 'tickets')
assert_equal(151, Ticket::Article.count, 'ticket articles') assert_equal(151, Ticket::Article.count, 'ticket articles')

View file

@ -10,4 +10,41 @@ class PermissionTest < ActiveSupport::TestCase
assert_equal(2, permissions.count) assert_equal(2, permissions.count)
end end
test 'user permission' do
Permission.create_if_not_exists(
name: 'admin.permission1',
note: 'Admin Interface',
preferences: {},
)
role_permission1 = Role.create_or_update(
name: 'AdminPermission1',
note: 'To configure your permission1.',
preferences: {
not: ['Customer'],
},
default_at_signup: false,
updated_by_id: 1,
created_by_id: 1,
)
role_permission1.permission_grand('admin.permission1')
user_with_permission1 = User.create_or_update(
login: 'setting-permission1',
firstname: 'Setting',
lastname: 'Admin Permission1',
email: 'setting-admin-permission1@example.com',
password: 'some_pw',
active: true,
roles: [role_permission1],
updated_by_id: 1,
created_by_id: 1,
)
assert_equal(true, user_with_permission1.permissions?('admin.permission1'))
assert_equal(true, user_with_permission1.permissions?('admin.*'))
assert_equal(false, user_with_permission1.permissions?('admi.*'))
assert_equal(false, user_with_permission1.permissions?('admin.permission2'))
assert_equal(false, user_with_permission1.permissions?('admin'))
end
end end