Skip to content
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

feat(authorization): implement application prefix permission source #490

Merged
merged 9 commits into from
Oct 28, 2019

Conversation

AbdulRahmanAlHamali
Copy link
Contributor

@AbdulRahmanAlHamali AbdulRahmanAlHamali commented Oct 23, 2019

This is still a draft
This PR allows users to provide permissions to applications using name prefixes specified like:

  • "*"
  • "abc*"
  • etc.

@spinnakerbot
Copy link
Contributor

The following commits need their title changed:

Please format your commit title into the form:

<type>(<scope>): <subject>, e.g. fix(kubernetes): address NPE in status check

This allows us to easily generate changelogs & determine semantic version numbers when cutting releases. You can read more about commit conventions here.

Copy link
Contributor

@cfieber cfieber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a good start

would like to see the Prefix source end up generic rather than Application specific (should be simple enough)

some notes on the Spring framework init'ing that I think will have to be addressed for this to work properly

import javax.annotation.Nonnull;
import lombok.Data;

@Data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be a @Data

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh I see why you added this (deserializing from jackson..)

I have a more Spring-y alternative to suggest

@Bean
@ConditionalOnExpression(
"T(org.springframework.utils.CollectionUtils).isNotEmpty(${auth.permissions.source.application.prefix})")
List<ResourcePermissionSource<Application>> applicationPrefixPermissionSource(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure you can return a List here and have that List merged in with all the other single beans of type ResourcePermissionSource (for example to use aggregation)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see the comment in ApplicationPrefixPermissionSource above - this should either return one ResourcePermissionSource that can handle all the supplied prefixes, or create one instance per prefix but then register those with the applicationContext

import lombok.Data;

@Data
public class ApplicationPrefixPermissionSource implements ResourcePermissionSource<Application> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this a singleton component that accepts the configuration map of prefix -> permissions

in getPermissions iterate over the map finding matching keys (I guess all matching prefixes considering there could be overlap) and build up the resulting Permissions object from that

This could be made generic (PrefixResourcePermissionSource<T extends Resource> implements ResourcePermissionSource<T>) since there really isn't anything Application specific in here and I could definitely see legitimate uses for this on Account/BuildService as well. (In DefaultResourcePermissionConfig you could still just create the one for T = Application for now)

If you think it is more appropriate to create an instance of this per prefix mapping within a type to allow fancier ResourcePermissionProvider aggregating, it should still be done via constructor args rather than @Data and a setter. In that case you'll need to update the DefaultResourcePermissionConfig to create each instance and register it with the configurableApplicationContext.getBeanFactory().registerSingleton("name", prefixSpecificSource) rather than returning a List.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for the rushed implementation. I wanted to submit something quick for you to look at before I went home.

I will fix the way permissions are read from the config. But regarding having just one source that contains all the prefixes, I preferred to have one source per prefix, because, as you mentioned, it will allow to resolve them using any desired provider. If I put their resolution logic inside the source, I will be replicating the work of the AggregatingResourcePermissionProvider. Also, it might be desired to resolve them in different ways. For example, more specific might be desired to override less specific, which will be harder to do if I rule what resolution logic should be supported.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, I think multiple sources is the right way to go

@AbdulRahmanAlHamali
Copy link
Contributor Author

I have reimplemented this as a single source. Implementing it as multiple sources and getting the beans to load correctly in Spring was very hacky and error-prone. So now it is a single source with multiple prefixes, and a resolution strategy which could either be aggregate or most_specific.

I also added the ability to add a full name, in which case I do exact matching. This allows prefix source to function on its own without any other sources if the admin desires.

Copy link
Contributor

@cfieber cfieber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

}

private List<PrefixEntry<T>> prefixes;
private ResolutionStrategy resolutionStrategy;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to have a default here? (AGGREGATE perhaps?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, but I wonder if we should do that in the config instead of here

@cfieber cfieber merged commit 37ac06d into spinnaker:master Oct 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants