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
[WIP][JENKINS-58293] Folder based Authorization as a new AuthorizationStrategy #89
[WIP][JENKINS-58293] Folder based Authorization as a new AuthorizationStrategy #89
Conversation
* | ||
* @param globalRoles set of roles from which to calculate the permissions. | ||
*/ | ||
GlobalAclImpl(Set<GlobalRole> globalRoles) { |
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.
This is a new implementation for global roles. When the object is created, it pre-computes all permissions available to the sid by going through all of the roles.
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.
Would it make sense to do it in a separate pull request? From what I see, the existing strategy could benefit from it as well
for (GlobalRole role : globalRoles) { | ||
Set<Permission> impliedPermissions = ConcurrentHashMap.newKeySet(); | ||
|
||
role.permissions.parallelStream() |
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.
I'm using parallel streams here and a thread-safe set. Please let me know if I need to revert back to single-threaded streams.
protected Boolean hasPermission(Sid p, Permission permission) { | ||
Set<Permission> permissions = permissionList.get(toString(p)); | ||
if (permission != null && permissions.contains(permission)) { | ||
return true; |
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.
hasPermission
should now run in constant time (O(1)
) because getting a value from a map and checking if something is contained in a set are both O(1) operations.
7274648
to
15d7222
Compare
The POST request is currently not handled properly
src/main/java/io/jenkins/plugins/rolestrategy/GlobalRoleCreationRequest.java
Outdated
Show resolved
Hide resolved
|
||
// this is really bad. | ||
// See https://github.com/jenkinsci/jenkins/blob/75468da366c1d257a51655dcbe952d55b8aeeb9c/war/src/main/js/util/jenkins.js#L22 | ||
const oldPrototype = Array.prototype.toJSON; |
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.
I've implemented the same fix in the link
What would be the URL to import and use the file directly?
* | ||
* @param globalRoles set of roles from which to calculate the permissions. | ||
*/ | ||
GlobalAclImpl(Set<GlobalRole> globalRoles) { |
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.
Would it make sense to do it in a separate pull request? From what I see, the existing strategy could benefit from it as well
@CheckForNull | ||
@Override | ||
public String getDisplayName() { | ||
return "Folder Authorization Strategy"; |
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.
Would be nice to make it localizable for the final implementation
src/main/java/io/jenkins/plugins/rolestrategy/GlobalRoleCreationRequest.java
Outdated
Show resolved
Hide resolved
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.
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
@ParametersAreNonnullByDefault |
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.
IIRC it is not going to play well for the transient field. SportBugs/FindBugs are not equipped to resolve such deserialization cases IIRC
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
public class GlobalAclImplTest { |
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.
JCasC compatibility autotest here would be really interesting
* Also remove `forEach` from JavaScript as it is not compatible with old browsers * Make the dependency on Cloudbees folder plugin optional * Update Jelly UI * Make GlobalRoleCreationRequest `@Restricted(NoExternalUse.class)`
* Refactor roles and ACLs into their own packages * Update the Jelly UI a bit
The test fails because
|
Would it be fine to create a pull request to Jenkins core and add |
You can whitelist it for the plugin . |
src/main/java/io/jenkins/plugins/rolestrategy/FolderAuthorizationStrategyManagementLink.java
Show resolved
Hide resolved
* Also make AbstractRole `@Restricted(NoExternalUse.class)` * Add some JavaDoc
ff05362
to
bf50316
Compare
src/main/java/io/jenkins/plugins/rolestrategy/FolderAuthorizationStrategyManagementLink.java
Outdated
Show resolved
Hide resolved
@@ -0,0 +1 @@ | |||
java.util.concurrent.ConcurrentHashMap$KeySetView |
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.
Bad idea. Fix your code to store a simpler type instead, like an ArrayList
.
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.
Hi @jglick ! I had wanted to use a Set
to avoid duplicates and for faster remove()
operations. Also since there were tickets for concurrency issues in the Role Strategy Plugin, this seemed like the perfect option. Could you please let me know why you think this is a bad idea? Also as an alternative, would you approve of CopyOnWriteArraySet
? remove()
s will be slower but we'll get thread safety and avoid duplicates.
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.
Add a writeReplace() method to convert the class to a serialization proxy, then inside that proxy class create a readResolve() method to convert the proxy class back to the original class. I've come across this exact same whitelisting issue twice so far in the past year.
Edit: here's an example of how I worked around this issue: https://github.com/jenkinsci/support-core-plugin/blob/master/src/main/java/com/cloudbees/jenkins/support/filter/ContentMappings.java
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.
faster
remove()
operations
This smells wrong. How often are you modifying this set anyway? If it is being persisted in XStream, then any collection overhead would be orders of magnitude less than disk I/O when the result is saved.
Could you please let me know why you think this is a bad idea?
Data stored by a plugin should use simple types. There are good reasons to create a custom ClassFilter
whitelist in a plugin; this is not one of them.
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.
* Use the CasC incremental * Use AbstractFolders instead of Folders
Unrelated build failure:
|
Hi everyone! We decided to move this code to a new repository: https://github.com/jenkinsci/folder-auth-plugin . For the issues above, I'm creating new JIRA tickets. I would love to hear your feedback there. Thanks! |
Unlike #87 this adds a new
@Extension
with Authorization StrategyThis is a work in progress pull request