-
Notifications
You must be signed in to change notification settings - Fork 135
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
Add CA ProfileService to v2 API #4811
Conversation
if (authToken == null) | ||
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.
Could we move this into the if
clause (between line 1197 and 1198) since in the else
clause it cannot be null
?
IIUC the original code lets members of Here's the default ACL for that resource (formatted for readability):
So the new code will grant access to @ladycfu What do you think? The rest of the code looks fine to me. |
A more restrictive operation would be to use the ACL:
In this case only the If we would be more flexible we could allow all the people with read access:
Currently, the ProfileService uses ACL with the following mapping:
|
I'll let @ladycfu decide on how the ACL should look like, but regardless, this change will require performing an @fmarco76 If you want, we can merge the PR with the original (i.e. hard-coded) ACL first, then do the ACL change in a separate PR. |
Is this needed only if we define a new ACL? In my test, with existing ACL I had no need to modify the stored information. |
To my understanding the ACL is imported from LDIF file into LDAP during installation, and the server will only use the ACL in LDAP, not in LDIF. So if we only modify the ACL in LDIF (either adding new ACL or modifying an existing one) the changes will only appear in new installations, and existing installations will still have the old ACL in LDAP unless we explicitly modify the LDAP as well. |
} | ||
if (authToken == null) | ||
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.
could the checkRealm() method in AuthzSubsystem.java be used here instead?
Not looking at the code, but just a quick reply to how I envision the policy works: 1. Both CA admins and agents should be allowed to view/list all profiles, regardless of visibility. Visibility setting should only affect non-admin and non-agent users (actually, I don't think there is any security impact on letting users see disabled profiles, but I think it'll be less messy when list of profiles are presented to users). 2. CA admins can only modify disabled profiles and cannot enable/disable a profile 3. CA agents cannot modify any profiles, but could disable/enable a profile. |
I should add that CA admins are also allowed to add profiles, but in a disabled state. An agent is expected to review and enable the new profile to show approval. I'm not sure about deletion of profiles, but I supposed it should be fine to leave that to the admins. |
0d09dce
to
80f24f8
Compare
Update the ACL to certServer.profile.configuration,read which should work as expected. |
} | ||
} | ||
|
||
private boolean isProfileAccessLimited(Principal principal) { |
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.
If I read this correctly, this is just to check whether principal has "read" access? I'm just curious why it is named "isProfileAccessLimited", and all callers have the return value assigned to visibleOnly
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.
Yes, the actual check is done by this code below which returns false
if the user has a read
access:
AuthzToken authzToken = authzSubsystem.authorize(
authzMgrName,
authToken,
"certServer.profile.configuration",
"read");
if (authzToken != null)
return false;
The visibleOnly
variable comes from the original code which actually means "only allowed to access visible profiles" or "not allowed to access invisible profiles":
https://github.com/dogtagpki/pki/blob/master/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v1/ProfileService.java#L126-L134
I believe the isProfileAccessLimited()
method name was given to match the meaning of visibleOnly
, but I think they are both rather confusing since we'd have to mentally invert them to understand what they do. To make it easier to understand I'd suggest renaming them to something like allowedToAccessInvisibleProfiles
and isAllowedToAccessInvisibleProfiles()
, respectively, and flip the logic everywhere it's used.
String userid = principal.getName(); | ||
try { | ||
if (ps.checkOwner()) { | ||
if (ps.getProfileEnableBy(profileId).equals(userid)) { |
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 checking to see whether the profile was enabled by the same uid that's trying to disable it now. I think the policy we want is just to check whether the person that's trying to disable the profile is a CA agent. Let's say if Joe was a CA agent who enabled a profile, but later his CA agent privilege was removed, then he can't be allowed to disable the profile (although I suspect the ACL was checked before this... once my other question above is answered). Also, as long as the person is a CA agent, they are allowed to disable/enable a profile. They do not need to be the same person.
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 believe this code is basically identical to the original code here:
https://github.com/dogtagpki/pki/blob/master/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v1/ProfileService.java#L449-L475
In this PR we're just trying to convert the original RESTEasy-based service into a plain servlet so we can drop the RESTEasy dependency later on, but the functionality should be pretty much identical. I think @fmarco76 is trying to fix the hard-coded ACL too, but the behavior should still be unchanged (which is why it's a bit complicated).
If the behavior of the original code itself is not correct we probably should review how this feature is tested and documented.
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.
@edewata thanks. yeah it's okay to create a new follow-up ticket to change the behavior to meet what we need. Basically "checkOwner" is not needed, as long as the user is a CA agent. Although it does make one wonder why no one has complained about it.
throw new ConflictingOperationException("Profile already enabled"); | ||
} | ||
try { | ||
ps.enableProfile(profileId, principal.getName()); |
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.
@edewata I know Marco is out on pto, so maybe you could help explain to me where the ACL for checking for the CA agent membership of the principal is held?
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.
Please see my comments here:
#4811 (comment)
#4811 (comment)
So the original code checks whether the user is a member of Certificate Manager Agents
or Certificate Manager Administrators
directly, and the new code checks whether the user has read
access to certServer.profile.configuration
using ACL, but IIUC they are not identical replacements, that's my concern with this change.
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.
thanks @edewata . So, with the clarification that this task is to replace the rest interface with the same policy, I agree with Endi that the code in this patch here isn't identical. Although I have to add that as I stated earlier, only CA agents should have the privilege to enable or disable a profile. I'll leave it to you two to decide whether to change it to the original behavior for this patch now, then create a separate ticket to change it to the desired behavior I stated, or simply change it to match the desired behavior.
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.
see comments.
throw new ConflictingOperationException("Profile already enabled"); | ||
} | ||
try { | ||
ps.enableProfile(profileId, principal.getName()); |
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.
thanks @edewata . So, with the clarification that this task is to replace the rest interface with the same policy, I agree with Endi that the code in this patch here isn't identical. Although I have to add that as I stated earlier, only CA agents should have the privilege to enable or disable a profile. I'll leave it to you two to decide whether to change it to the original behavior for this patch now, then create a separate ticket to change it to the desired behavior I stated, or simply change it to match the desired behavior.
String userid = principal.getName(); | ||
try { | ||
if (ps.checkOwner()) { | ||
if (ps.getProfileEnableBy(profileId).equals(userid)) { |
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.
@edewata thanks. yeah it's okay to create a new follow-up ticket to change the behavior to meet what we need. Basically "checkOwner" is not needed, as long as the user is a CA agent. Although it does make one wonder why no one has complained about it.
ACL groups does not match with the embedded checks in v1 code so the code has been reverted to the embedded check leaving the ACL update to future commits.
f5ec6dd
to
d9d35c9
Compare
Quality Gate passedIssues Measures |
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.
Thanks for the update! Yeah, I think we can merge it.
So for the ACL, if we decide later to change it, we need to figure out how to upgrade the existing ACL in LDAP first (if needed) before we can change the ACL.
Implementing the
Profile
in v2 APIs I have done replaced the check for the user authorisation from the hardcoded to the authorisation manager (see methodisProfileAccessLimited(Principal)
inProfileBase
).The logic is that user with modify access can access the not visible profiles. @edewata Is this OK or do we need a different ACL?