Added role management.
This commit is contained in:
parent
b61068a13a
commit
e5999fe71d
13 changed files with 459 additions and 30 deletions
|
@ -1,6 +1,6 @@
|
|||
# coffeelint: disable=camel_case_classes
|
||||
class App.UiElement.permission extends App.UiElement.ApplicationUiElement
|
||||
@render: (attribute, params) ->
|
||||
@render: (attribute, params = {}) ->
|
||||
|
||||
permissions = App.Permission.search(sortBy: 'name')
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@ class Index extends App.Controller
|
|||
App.Ajax.request(
|
||||
id: 'preferences'
|
||||
type: 'PUT'
|
||||
url: @apiPath + '/users/preferences'
|
||||
url: "#{@apiPath}/users/preferences"
|
||||
data: JSON.stringify({user:{intro:true}})
|
||||
processData: true
|
||||
)
|
||||
@navigate '#'
|
||||
)
|
||||
|
||||
App.Config.set( 'clues', Index, 'Routes' )
|
||||
App.Config.set('clues', Index, 'Routes')
|
||||
|
|
|
@ -7,7 +7,7 @@ class App.Dashboard extends App.Controller
|
|||
constructor: ->
|
||||
super
|
||||
|
||||
if @permissionCheck('ticket.customer')
|
||||
if !@permissionCheck('ticket.agent')
|
||||
@clueAccess = false
|
||||
return
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ App.Config.set('channels/:target/:channel_id', IndexRouter, 'Routes')
|
|||
App.Config.set('system/:target', IndexRouter, 'Routes')
|
||||
App.Config.set('system/:target/:integration', IndexRouter, 'Routes')
|
||||
|
||||
App.Config.set('Manage', { prio: 1000, name: 'Manage', target: '#manage', role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('Channels', { prio: 2500, name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('Settings', { prio: 7000, name: 'Settings', target: '#settings', role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('System', { prio: 8000, name: 'System', target: '#system', role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('Manage', { prio: 1000, name: 'Manage', target: '#manage', permission: ['admin.*'] }, 'NavBarAdmin')
|
||||
App.Config.set('Channels', { prio: 2500, name: 'Channels', target: '#channels', permission: ['admin.*'] }, 'NavBarAdmin')
|
||||
App.Config.set('Settings', { prio: 7000, name: 'Settings', target: '#settings', permission: ['admin.*'] }, 'NavBarAdmin')
|
||||
App.Config.set('System', { prio: 8000, name: 'System', target: '#system', permission: ['admin.*'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -406,7 +406,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
recentViewNavbarItemsRebuild: =>
|
||||
|
||||
# remove old views
|
||||
NavBarRight = @Config.get( 'NavBarRight' ) || {}
|
||||
NavBarRight = @Config.get('NavBarRight') || {}
|
||||
for key of NavBarRight
|
||||
if NavBarRight[key].parent is '#current_user'
|
||||
part = key.split '::'
|
||||
|
|
25
app/assets/javascripts/app/controllers/role.coffee
Normal file
25
app/assets/javascripts/app/controllers/role.coffee
Normal file
|
@ -0,0 +1,25 @@
|
|||
class Index extends App.ControllerContent
|
||||
requiredPermission: 'admin.role'
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
new App.ControllerGenericIndex(
|
||||
el: @el
|
||||
id: @id
|
||||
genericObject: 'Role'
|
||||
pageData:
|
||||
title: 'Roles'
|
||||
home: 'roles'
|
||||
object: 'Role'
|
||||
objects: 'Roles'
|
||||
navupdate: '#roles'
|
||||
notes: [
|
||||
'Roles are ...'
|
||||
]
|
||||
buttons: [
|
||||
{ name: 'New Role', 'data-type': 'new', class: 'btn--success' }
|
||||
]
|
||||
container: @el.closest('.content')
|
||||
)
|
||||
|
||||
App.Config.set('Role', { prio: 1600, name: 'Roles', parent: '#manage', target: '#manage/roles', controller: Index, permission: ['admin.role'] }, 'NavBarAdmin')
|
|
@ -172,6 +172,8 @@ class App.User extends App.Model
|
|||
|
||||
result = user.permission('user_preferences.calendar+ticket.agent') # access must have two permission keys
|
||||
|
||||
result = user.permission('admin.*') # access if one sub key access exists
|
||||
|
||||
returns
|
||||
|
||||
true|false
|
||||
|
@ -190,9 +192,10 @@ class App.User extends App.Model
|
|||
permissions = {}
|
||||
for role_id in @role_ids
|
||||
role = App.Role.find(role_id)
|
||||
for permission_id in role.permission_ids
|
||||
permission = App.Permission.find(permission_id)
|
||||
permissions[permission.name] = true
|
||||
if role.active is true
|
||||
for permission_id in role.permission_ids
|
||||
permission = App.Permission.find(permission_id)
|
||||
permissions[permission.name] = true
|
||||
|
||||
for localKey in keys
|
||||
requiredPermissions = localKey.split('+')
|
||||
|
@ -200,12 +203,25 @@ class App.User extends App.Model
|
|||
for requiredPermission in requiredPermissions
|
||||
localAccess = false
|
||||
partString = ''
|
||||
for part in requiredPermission.split('.')
|
||||
if partString isnt ''
|
||||
partString += '.'
|
||||
partString += part
|
||||
if permissions[partString]
|
||||
localAccess = true
|
||||
parts = requiredPermission.split('.')
|
||||
|
||||
# verify name.* permissions
|
||||
if parts[parts.length - 1] is '*'
|
||||
for permission_key, permission_value of permissions
|
||||
if permission_value is true
|
||||
length = requiredPermission.length - 1
|
||||
if permission_key.substr(0, length) is requiredPermission.substr(0, length)
|
||||
localAccess = true
|
||||
|
||||
# verify name.explicite permissions
|
||||
if !localAccess
|
||||
for part in parts
|
||||
if partString isnt ''
|
||||
partString += '.'
|
||||
partString += part
|
||||
if permissions[partString]
|
||||
localAccess = true
|
||||
|
||||
if localAccess
|
||||
access = true
|
||||
else
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
<% if @groups: %>
|
||||
<% for group in @groups: %>
|
||||
<h2><%- @T(group.name) %></h2>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<% if group.items: %>
|
||||
<% for item in group.items: %>
|
||||
<li <% if item.active: %>class="active"<% end %>><a href="<%= item.target %>"><%- @T(item.name) %></a></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% if !_.isEmpty(group.items): %>
|
||||
<h2><%- @T(group.name) %></h2>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<% if group.items: %>
|
||||
<% for item in group.items: %>
|
||||
<li <% if item.active: %>class="active"<% end %>><a href="<%= item.target %>"><%- @T(item.name) %></a></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<% for permission in @permissions: %>
|
||||
<% if !permission.name.match(/\./): %>
|
||||
<label class="inline-label checkbox-replacement">
|
||||
<input type="checkbox" value="<%= permission.id %>" name="permission_ids" <% if _.contains(@params.permission_ids, permission.id): %>checked<% end %> <% if permission.preferences.disabled: %>disabled<% end %>/>
|
||||
<input type="checkbox" value="<%= permission.id %>" name="permission_ids" <% if _.contains(@params.permission_ids, permission.id): %>checked<% end %> <% if permission.preferences.disabled: %>disabled<% end %> data-permission-name="<%= permission.name %>"/>
|
||||
<%- @Icon('checkbox', 'icon-unchecked') %>
|
||||
<%- @Icon('checkbox-checked', 'icon-checked') %>
|
||||
<span class="label-text"><%= permission.displayName() %> - <span class="help-text"><%- @T.apply(@, [permission.note].concat(permission.preferences.translations)) %></span></span>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<% else: %>
|
||||
<div style="padding-left: 20px;" class="js-subPermissionList">
|
||||
<label class="inline-label checkbox-replacement">
|
||||
<input type="checkbox" value="<%= permission.id %>" name="permission_ids" <% if _.contains(@params.permission_ids, permission.id): %>checked<% end %> <% if permission.preferences.disabled: %>disabled<% end %>/>
|
||||
<input type="checkbox" value="<%= permission.id %>" name="permission_ids" <% if _.contains(@params.permission_ids, permission.id): %>checked<% end %> <% if permission.preferences.disabled: %>disabled<% end %> data-permission-name="<%= permission.name %>"/>
|
||||
<%- @Icon('checkbox', 'icon-unchecked') %>
|
||||
<%- @Icon('checkbox-checked', 'icon-checked') %>
|
||||
<span class="label-text"><%= permission.displayName().replace(/^.+?\./, '') %> - <span class="help-text"><%- @T.apply(@, [permission.note].concat(permission.preferences.translations)) %></span></span>
|
||||
|
|
|
@ -374,10 +374,10 @@ returns
|
|||
if local_key =~ /\.\*$/
|
||||
local_key.sub!('.*', '.%')
|
||||
permissions = Object.const_get('Permission').with_parents(local_key)
|
||||
list = Object.const_get('Permission').select('preferences').joins(:roles).where('roles.id IN (?) AND (permissions.name IN (?) OR permissions.name LIKE ?)', role_ids, permissions, local_key).pluck(:preferences)
|
||||
list = Object.const_get('Permission').select('preferences').joins(:roles).where('roles.id IN (?) AND roles.active = ? AND (permissions.name IN (?) OR permissions.name LIKE ?)', role_ids, true, permissions, local_key).pluck(:preferences)
|
||||
else
|
||||
permissions = Object.const_get('Permission').with_parents(local_key)
|
||||
list = Object.const_get('Permission').select('preferences').joins(:roles).where('roles.id IN (?) AND permissions.name IN (?)', role_ids, permissions).pluck(:preferences)
|
||||
list = Object.const_get('Permission').select('preferences').joins(:roles).where('roles.id IN (?) AND roles.active = ? AND permissions.name IN (?)', role_ids, true, permissions).pluck(:preferences)
|
||||
end
|
||||
list.each { |preferences|
|
||||
next if preferences[:selectable] == false
|
||||
|
|
128
test/browser/admin_role_test.rb
Normal file
128
test/browser/admin_role_test.rb
Normal file
|
@ -0,0 +1,128 @@
|
|||
# encoding: utf-8
|
||||
require 'browser_test_helper'
|
||||
|
||||
class AdminRoleTest < TestCase
|
||||
def test_role
|
||||
name = "some role #{rand(99_999_999)}"
|
||||
|
||||
@browser = browser_instance
|
||||
login(
|
||||
username: 'master@example.com',
|
||||
password: 'test',
|
||||
url: browser_url,
|
||||
)
|
||||
tasks_close_all()
|
||||
|
||||
rand = rand(99_999_999).to_s
|
||||
login = 'agent-role-' + rand
|
||||
firstname = 'Role' + rand
|
||||
lastname = 'Module' + rand
|
||||
email = 'agent-role-' + rand + '@example.com'
|
||||
password = 'agentpw'
|
||||
|
||||
user_create(
|
||||
data: {
|
||||
login: login,
|
||||
firstname: firstname,
|
||||
lastname: lastname,
|
||||
email: email,
|
||||
password: password,
|
||||
},
|
||||
)
|
||||
|
||||
name = "somerole#{rand}"
|
||||
role_create(
|
||||
data: {
|
||||
name: name,
|
||||
default_at_signup: false,
|
||||
permission: [
|
||||
'admin.group',
|
||||
'user_preferences.device',
|
||||
],
|
||||
member: [login],
|
||||
}
|
||||
)
|
||||
|
||||
logout()
|
||||
login(
|
||||
username: email,
|
||||
password: password,
|
||||
url: browser_url,
|
||||
)
|
||||
tasks_close_all()
|
||||
click(css: 'a[href="#current_user"]')
|
||||
click(css: 'a[href="#profile"]')
|
||||
match(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Password',
|
||||
)
|
||||
match(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Language',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Notifications',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Calendar',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Token Access',
|
||||
)
|
||||
match(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Devices',
|
||||
)
|
||||
|
||||
logout()
|
||||
login(
|
||||
username: 'master@example.com',
|
||||
password: 'test',
|
||||
url: browser_url,
|
||||
)
|
||||
role_edit(
|
||||
data: {
|
||||
name: name,
|
||||
active: false,
|
||||
}
|
||||
)
|
||||
|
||||
logout()
|
||||
login(
|
||||
username: email,
|
||||
password: password,
|
||||
url: browser_url,
|
||||
)
|
||||
tasks_close_all()
|
||||
click(css: 'a[href="#current_user"]')
|
||||
click(css: 'a[href="#profile"]')
|
||||
match(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Password',
|
||||
)
|
||||
match(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Language',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Notifications',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Calendar',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Token Access',
|
||||
)
|
||||
match_not(
|
||||
css: '.content .NavBarProfile',
|
||||
value: 'Devices',
|
||||
)
|
||||
end
|
||||
|
||||
end
|
|
@ -2820,6 +2820,217 @@ wait untill text in selector disabppears
|
|||
raise 'group creation failed'
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
role_create(
|
||||
browser: browser2,
|
||||
data: {
|
||||
name: 'some role' + random,
|
||||
default_at_signup: false,
|
||||
permission: [
|
||||
'admin.group',
|
||||
'preferences.password',
|
||||
],
|
||||
member: [
|
||||
'some_user_login',
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
=end
|
||||
|
||||
def role_create(params = {})
|
||||
switch_window_focus(params)
|
||||
log('role_create', params)
|
||||
|
||||
instance = params[:browser] || @browser
|
||||
data = params[:data]
|
||||
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[href="#manage"]',
|
||||
mute_log: true,
|
||||
)
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[href="#manage/roles"]',
|
||||
mute_log: true,
|
||||
)
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[data-type="new"]',
|
||||
mute_log: true,
|
||||
)
|
||||
modal_ready(browser: instance)
|
||||
element = instance.find_elements(css: '.modal input[name=name]')[0]
|
||||
element.clear
|
||||
element.send_keys(data[:name])
|
||||
|
||||
if data.key?(:default_at_signup)
|
||||
element = instance.find_elements(css: '.modal select[name="default_at_signup"]')[0]
|
||||
dropdown = Selenium::WebDriver::Support::Select.new(element)
|
||||
if data[:default_at_signup] == true
|
||||
dropdown.select_by(:text, 'yes')
|
||||
else
|
||||
dropdown.select_by(:text, 'no')
|
||||
end
|
||||
end
|
||||
|
||||
if data.key?(:permission)
|
||||
data[:permission].each { |permission_name|
|
||||
check(
|
||||
browser: instance,
|
||||
css: ".modal [data-permission-name=\"#{permission_name}\"]",
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
modal_disappear(browser: instance)
|
||||
11.times {
|
||||
element = instance.find_elements(css: 'body')[0]
|
||||
text = element.text
|
||||
if text =~ /#{Regexp.quote(data[:name])}/
|
||||
assert(true, 'role created')
|
||||
modal_disappear(browser: instance) # wait until modal has gone
|
||||
|
||||
# add member
|
||||
if data[:member]
|
||||
data[:member].each { |login|
|
||||
instance.find_elements(css: 'a[href="#manage"]')[0].click
|
||||
sleep 1
|
||||
instance.find_elements(css: 'a[href="#manage/users"]')[0].click
|
||||
sleep 3
|
||||
element = instance.find_elements(css: '#content [name="search"]')[0]
|
||||
element.clear
|
||||
element.send_keys(login)
|
||||
sleep 3
|
||||
#instance.find_elements(:css => '#content table [data-id]')[0].click
|
||||
instance.execute_script('$("#content table [data-id] td").first().click()')
|
||||
sleep 3
|
||||
#instance.find_elements(:css => 'label:contains(" ' + action[:name] + '")')[0].click
|
||||
instance.execute_script('$(\'label:contains(" ' + data[:name] + '")\').first().click()')
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
modal_disappear(browser: instance)
|
||||
}
|
||||
end
|
||||
end
|
||||
sleep 1
|
||||
return true
|
||||
}
|
||||
screenshot(browser: instance, comment: 'role_create_failed')
|
||||
raise 'role creation failed'
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
role_create(
|
||||
browser: browser2,
|
||||
data: {
|
||||
name: 'some role' + random,
|
||||
default_at_signup: false,
|
||||
permission: [
|
||||
'admin.group',
|
||||
'preferences.password',
|
||||
],
|
||||
member: [
|
||||
'some_user_login',
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
=end
|
||||
|
||||
def role_edit(params = {})
|
||||
switch_window_focus(params)
|
||||
log('role_edit', params)
|
||||
|
||||
instance = params[:browser] || @browser
|
||||
data = params[:data]
|
||||
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[href="#manage"]',
|
||||
mute_log: true,
|
||||
)
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[href="#manage/roles"]',
|
||||
mute_log: true,
|
||||
)
|
||||
instance.execute_script('$(\'#content table tr td:contains(" ' + data[:name] + '")\').first().click()')
|
||||
|
||||
modal_ready(browser: instance)
|
||||
element = instance.find_elements(css: '.modal input[name=name]')[0]
|
||||
element.clear
|
||||
element.send_keys(data[:name])
|
||||
|
||||
if data.key?(:default_at_signup)
|
||||
element = instance.find_elements(css: '.modal select[name="default_at_signup"]')[0]
|
||||
dropdown = Selenium::WebDriver::Support::Select.new(element)
|
||||
if data[:default_at_signup] == true
|
||||
dropdown.select_by(:text, 'yes')
|
||||
else
|
||||
dropdown.select_by(:text, 'no')
|
||||
end
|
||||
end
|
||||
|
||||
if data.key?(:permission)
|
||||
data[:permission].each { |permission_name|
|
||||
check(
|
||||
browser: instance,
|
||||
css: ".modal [data-permission-name=\"#{permission_name}\"]",
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
if data.key?(:active)
|
||||
element = instance.find_elements(css: '.modal select[name="active"]')[0]
|
||||
dropdown = Selenium::WebDriver::Support::Select.new(element)
|
||||
if data[:active] == true
|
||||
dropdown.select_by(:text, 'active')
|
||||
else
|
||||
dropdown.select_by(:text, 'inactive')
|
||||
end
|
||||
end
|
||||
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
modal_disappear(browser: instance)
|
||||
11.times {
|
||||
element = instance.find_elements(css: 'body')[0]
|
||||
text = element.text
|
||||
if text =~ /#{Regexp.quote(data[:name])}/
|
||||
assert(true, 'role created')
|
||||
modal_disappear(browser: instance) # wait until modal has gone
|
||||
|
||||
# add member
|
||||
if data[:member]
|
||||
data[:member].each { |login|
|
||||
instance.find_elements(css: 'a[href="#manage"]')[0].click
|
||||
sleep 1
|
||||
instance.find_elements(css: 'a[href="#manage/users"]')[0].click
|
||||
sleep 3
|
||||
element = instance.find_elements(css: '#content [name="search"]')[0]
|
||||
element.clear
|
||||
element.send_keys(login)
|
||||
sleep 3
|
||||
#instance.find_elements(:css => '#content table [data-id]')[0].click
|
||||
instance.execute_script('$("#content table [data-id] td").first().click()')
|
||||
sleep 3
|
||||
#instance.find_elements(:css => 'label:contains(" ' + action[:name] + '")')[0].click
|
||||
instance.execute_script('$(\'label:contains(" ' + data[:name] + '")\').first().click()')
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
modal_disappear(browser: instance)
|
||||
}
|
||||
end
|
||||
end
|
||||
sleep 1
|
||||
return true
|
||||
}
|
||||
screenshot(browser: instance, comment: 'role_edit_failed')
|
||||
raise 'role edit failed'
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
object_manager_attribute_create(
|
||||
|
|
|
@ -47,4 +47,51 @@ class PermissionTest < ActiveSupport::TestCase
|
|||
|
||||
end
|
||||
|
||||
test 'user permission with invalid role' do
|
||||
|
||||
Permission.create_if_not_exists(
|
||||
name: 'admin.permission2',
|
||||
note: 'Admin Interface',
|
||||
preferences: {},
|
||||
)
|
||||
role_permission2 = Role.create_or_update(
|
||||
name: 'AdminPermission2',
|
||||
note: 'To configure your permission2.',
|
||||
preferences: {
|
||||
not: ['Customer'],
|
||||
},
|
||||
default_at_signup: false,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
role_permission2.permission_grand('admin.permission2')
|
||||
user_with_permission2 = User.create_or_update(
|
||||
login: 'setting-permission2',
|
||||
firstname: 'Setting',
|
||||
lastname: 'Admin Permission2',
|
||||
email: 'setting-admin-permission2@example.com',
|
||||
password: 'some_pw',
|
||||
active: true,
|
||||
roles: [role_permission2],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert_equal(true, user_with_permission2.permissions?('admin.permission2'))
|
||||
assert_equal(true, user_with_permission2.permissions?('admin.*'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admi.*'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admin.permission3'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admin'))
|
||||
|
||||
role_permission2.active = false
|
||||
role_permission2.save
|
||||
user_with_permission2.reload
|
||||
assert_equal(false, user_with_permission2.permissions?('admin.permission2'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admin.*'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admi.*'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admin.permission3'))
|
||||
assert_equal(false, user_with_permission2.permissions?('admin'))
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue