summaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/role.rb26
-rw-r--r--app/models/user.rb19
2 files changed, 35 insertions, 10 deletions
diff --git a/app/models/role.rb b/app/models/role.rb
index 3ca4f92a1..870bbe945 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -198,11 +198,14 @@ class Role < ApplicationRecord
# action can be:
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
# * a permission Symbol (eg. :edit_project)
- def allowed_to?(action)
+ # scope can be:
+ # * an array of permissions which will be used as filter (logical AND)
+
+ def allowed_to?(action, scope=nil)
if action.is_a? Hash
- allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
+ allowed_actions(scope).include? "#{action[:controller]}/#{action[:action]}"
else
- allowed_permissions.include? action
+ allowed_permissions(scope).include? action
end
end
@@ -298,13 +301,20 @@ class Role < ApplicationRecord
private
- def allowed_permissions
- @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
+ def allowed_permissions(scope = nil)
+ scope = scope.sort if scope.present? # to maintain stable cache keys
+ @allowed_permissions ||= {}
+ @allowed_permissions[scope] ||= begin
+ unscoped = permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
+ scope.present? ? unscoped & scope : unscoped
+ end
end
- def allowed_actions
- @actions_allowed ||=
- allowed_permissions.inject([]) do |actions, permission|
+ def allowed_actions(scope = nil)
+ scope = scope.sort if scope.present? # to maintain stable cache keys
+ @actions_allowed ||= {}
+ @actions_allowed[scope] ||=
+ allowed_permissions(scope).inject([]) do |actions, permission|
actions += Redmine::AccessControl.allowed_actions(permission)
end.flatten
end
diff --git a/app/models/user.rb b/app/models/user.rb
index c1a860f5a..496084ceb 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -112,6 +112,7 @@ class User < Principal
attr_accessor :password, :password_confirmation, :generate_password
attr_accessor :last_before_login_on
attr_accessor :remote_ip
+ attr_writer :oauth_scope
LOGIN_LENGTH_LIMIT = 60
MAIL_LENGTH_LIMIT = 254
@@ -732,6 +733,20 @@ class User < Principal
end
end
+ def admin?
+ if authorized_by_oauth?
+ # when signed in via oauth, the user only acts as admin when the admin scope is set
+ super and @oauth_scope.include?(:admin)
+ else
+ super
+ end
+ end
+
+ # true if the user has signed in via oauth
+ def authorized_by_oauth?
+ !@oauth_scope.nil?
+ end
+
# Return true if the user is allowed to do the specified action on a specific context
# Action can be:
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
@@ -752,7 +767,7 @@ class User < Principal
roles.any? do |role|
(context.is_public? || role.member?) &&
- role.allowed_to?(action) &&
+ role.allowed_to?(action, @oauth_scope) &&
(block ? yield(role, self) : true)
end
elsif context && context.is_a?(Array)
@@ -771,7 +786,7 @@ class User < Principal
# authorize if user has at least one role that has this permission
roles = self.roles.to_a | [builtin_role]
roles.any? do |role|
- role.allowed_to?(action) &&
+ role.allowed_to?(action, @oauth_scope) &&
(block ? yield(role, self) : true)
end
else