-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature custom grant types #37
Open
flbulgarelli
wants to merge
19
commits into
master
Choose a base branch
from
feature-custom-grant-types
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
48b5885
Allowing grant to be extended
flbulgarelli 52a35f7
Extracting Base class
flbulgarelli 41090c8
Adding some docs
flbulgarelli 2af1e50
Introducing includes?
flbulgarelli 100c45b
Introducing granted_organizations
flbulgarelli 7990f82
Double dispatching allow
flbulgarelli a7d32f8
Removing to_mumukit_slug
flbulgarelli 3dc0ea5
Adding docs and renaming authorized_by?
flbulgarelli 9565e4c
Making includes? work with grant-likes to
flbulgarelli d3154ce
Implementing includes? by default
flbulgarelli 6d1d576
Renaming `authorizes?`
flbulgarelli 26ea92d
Renaming methods to be consistent with type
flbulgarelli 5baa1e6
Validating slug format
flbulgarelli bf387da
Correcting slug regexp
flbulgarelli 3827998
Extracting constant
flbulgarelli 32d8d3d
Improving validations
flbulgarelli f3d318c
Adding misisng validation
flbulgarelli b8bfc1f
Altering grants priority as @luchotc suggested
flbulgarelli 13fe905
fixing minor typos
luchotc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,43 @@ def to_mumukit_grant | |
end | ||
end | ||
|
||
module Mumukit::Auth::Grant | ||
|
||
# Parses a given string that describes a grant | ||
# by trying with each grant type, in the following order: | ||
# | ||
# 1. All grant | ||
# 2. Custom grants | ||
# 3. First Grant | ||
# 4. Slug grant | ||
# | ||
# Raises a `Mumukit::Auth::InvalidGrantFormatError` if the grant is not valid, which happens when | ||
# | ||
# * structure is invalid | ||
# * `something/_`, `_/something`, `_/_` format is used | ||
def self.parse(pattern) | ||
grant_types.each do |type| | ||
type.try_parse(pattern).try { |it| return it } | ||
end | ||
end | ||
|
||
module Mumukit::Auth | ||
class Grant | ||
def self.grant_types | ||
[AllGrant] + custom_grant_types + [FirstPartGrant, SingleGrant] | ||
end | ||
|
||
def self.add_custom_grant_type!(grant_type) | ||
custom_grant_types << grant_type | ||
end | ||
|
||
def self.remove_custom_grant_type!(grant_type) | ||
custom_grant_types.delete(grant_type) | ||
end | ||
|
||
def self.custom_grant_types | ||
@custom_grant_types ||= [] | ||
end | ||
|
||
class Base | ||
def as_json(options={}) | ||
to_s | ||
end | ||
|
@@ -15,6 +49,14 @@ def to_mumukit_grant | |
self | ||
end | ||
|
||
# returns the organizations that are explicitly | ||
# granted by this grant | ||
# | ||
# Custom grants may override this method | ||
def granted_organizations | ||
[] | ||
end | ||
|
||
def ==(other) | ||
other.class == self.class && to_s == other.to_s | ||
end | ||
|
@@ -29,68 +71,120 @@ def inspect | |
"<Mumukit::Auth::Grant #{to_s}>" | ||
end | ||
|
||
def self.parse(pattern) | ||
case pattern | ||
when '*' then | ||
AllGrant.new | ||
when '*/*' then | ||
AllGrant.new | ||
when /(.*)\/\*/ | ||
FirstPartGrant.new($1) | ||
else | ||
SingleGrant.new(Slug.parse pattern) | ||
end | ||
# Tells wether the given grant | ||
# is authorized by this grant | ||
# | ||
# This method exist in order to implement double dispatching | ||
# for both grant and slugs authorization | ||
# | ||
# See: | ||
# * `Mumukit::Auth::Slug#authorized_by?` | ||
# * `Mumukit::Auth::Grant::Base#allows? | ||
# * `Mumukit::Auth::Grant::Base#includes?` | ||
def authorized_by?(grant) | ||
grant.includes? self | ||
end | ||
|
||
# tells whether the given slug-like object is allowed by | ||
# this grant | ||
required :allows? | ||
|
||
# tells whether the given grant-like object is included | ||
# in - that is, is not broader than - this grant | ||
# | ||
# :warning: Custom grants **should not** override this method | ||
def includes?(grant_like) | ||
self == grant_like.to_mumukit_grant | ||
end | ||
|
||
# Returns a canonical string representation of this grant | ||
# Equivalent grant **must** have equivalent string representations | ||
required :to_s | ||
end | ||
|
||
class AllGrant < Grant | ||
def allows?(_resource_slug) | ||
class AllGrant < Base | ||
def allows?(_slug_like) | ||
true | ||
end | ||
|
||
def includes?(_) | ||
true | ||
end | ||
|
||
def to_s | ||
'*' | ||
end | ||
|
||
def to_mumukit_slug | ||
Mumukit::Auth::Slug.new '*', '*' | ||
def self.try_parse(pattern) | ||
new if ['*', '*/*'].include? pattern | ||
end | ||
end | ||
|
||
class FirstPartGrant < Grant | ||
class FirstPartGrant < Base | ||
attr_accessor :first | ||
|
||
def initialize(first) | ||
raise Mumukit::Auth::InvalidGrantFormatError, "Invalid first grant. First part must not be _" if first == '_' | ||
@first = first.downcase | ||
end | ||
|
||
def allows?(resource_slug) | ||
resource_slug.to_mumukit_slug.normalize!.match_first @first | ||
def granted_organizations | ||
[first] | ||
end | ||
|
||
def allows?(slug_like) | ||
slug_like.to_mumukit_slug.normalize!.match_first @first | ||
end | ||
|
||
def to_s | ||
"#{@first}/*" | ||
end | ||
|
||
def to_mumukit_slug | ||
Mumukit::Auth::Slug.new @first, '*' | ||
def includes?(grant_like) | ||
grant = grant_like.to_mumukit_grant | ||
case grant | ||
when FirstPartGrant then grant.first == first | ||
when SingleGrant then grant.slug.first == first | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could delegate
|
||
else false | ||
end | ||
end | ||
|
||
def self.try_parse(pattern) | ||
new($1) if pattern =~ /(.+)\/\*/ | ||
end | ||
end | ||
|
||
class SingleGrant < Grant | ||
class SingleGrant < Base | ||
attr_accessor :slug | ||
|
||
def initialize(slug) | ||
raise Mumukit::Auth::InvalidGrantFormatError, "Invalid slug grant. First part must not be _" if slug.first == '_' | ||
raise Mumukit::Auth::InvalidGrantFormatError, "Invalid slug grant. Second part must not be _" if slug.second == '_' | ||
@slug = slug.normalize | ||
end | ||
|
||
def allows?(resource_slug) | ||
resource_slug = resource_slug.to_mumukit_slug.normalize! | ||
resource_slug.match_first(@slug.first) && resource_slug.match_second(@slug.second) | ||
def granted_organizations | ||
[slug.first] | ||
end | ||
|
||
def allows?(slug_like) | ||
slug = slug_like.to_mumukit_slug.normalize! | ||
slug.match_first(@slug.first) && slug.match_second(@slug.second) | ||
end | ||
|
||
def to_s | ||
@slug.to_s | ||
end | ||
|
||
def to_mumukit_slug | ||
@slug | ||
def self.try_parse(pattern) | ||
new(Mumukit::Auth::Slug.parse pattern) | ||
rescue Mumukit::Auth::InvalidSlugFormatError => e | ||
raise Mumukit::Auth::InvalidGrantFormatError, "Invalid slug grant. Cause: #{e}" | ||
end | ||
end | ||
end | ||
|
||
module Mumukit::Auth | ||
class InvalidGrantFormatError < StandardError | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
module Mumukit::Auth::Protection | ||
def protect!(role, slug) | ||
def protect!(role, slug_like) | ||
raise Mumukit::Auth::UnauthorizedAccessError, | ||
"Unauthorized access to #{slug} as #{role}. Scope is `#{scope_for role}`" unless has_permission?(role, slug) | ||
"Unauthorized access to #{slug_like} as #{role}. Scope is `#{scope_for role}`" unless allows?(role, slug_like) | ||
end | ||
|
||
def protect_delegation!(other) | ||
other ||= {} | ||
raise Mumukit::Auth::UnauthorizedAccessError, | ||
"Unauthorized delegation to #{other.to_h}" unless delegate_to?(Mumukit::Auth::Permissions.parse(other.to_h)) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_grant_like
to make it more explicit?