-
-
Notifications
You must be signed in to change notification settings - Fork 489
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
Enhance static page with group user accessibility #7707
Enhance static page with group user accessibility #7707
Conversation
@@ -76,6 +81,9 @@ public class PagesAPI { | |||
|
|||
private final PageRepository pageRepository; | |||
|
|||
@Autowired |
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.
Suggest to move autowire to the constructor
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 don't find such practice within the whole Geonetwork project. Also the GN is using some old Spring version which I am little afraid of it does not support constructor type of injection. I would leave it for now to be consistent of overall geonetwork's coding standard.
web-ui/src/main/resources/catalog/templates/admin/settings/static-pages.html
Outdated
Show resolved
Hide resolved
…nced' into main.page.user.accessbility.enhanced
I am amending the feature to have multiple group selection option. Will post another version soon |
web/src/main/webapp/WEB-INF/classes/setup/sql/migrate/v443/migrate-default.sql
Outdated
Show resolved
Hide resolved
services/src/main/java/org/fao/geonet/api/pages/AccessExpression.java
Outdated
Show resolved
Hide resolved
@wangf1122 I'm testing the UI, but the groups panel doesn't seem enabled properly. I create a new static page, the groups panel is disabled, but when selecting the value The same when selecting other value, it's not disabled until I selected the value again. |
Did you refreshed your local CSS/JS cache? I dont seem to have such issue at my localhost. See below |
@wangf1122 yes, I did that and cleanup also the browser cache. See the attached screencast. static-pages.webm |
services/src/main/java/org/fao/geonet/api/pages/model/GroupAccessExpression.java
Outdated
Show resolved
Hide resolved
@@ -114,4 +123,12 @@ public String getIcon() { | |||
public void setIcon(String icon) { | |||
this.icon = icon; | |||
} | |||
|
|||
public List<String> getGroups() { |
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.
The main concern is about not using referential integrity with the groups table.
Could be maybe check as a similar example the User
-> Address
relationship:
core-geonetwork/domain/src/main/java/org/fao/geonet/domain/User.java
Lines 223 to 244 in 88cc425
/** * Get all the user's addresses. * * @return all the user's addresses. */ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinTable(name = "UserAddress", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = {@JoinColumn(name = "addressid", referencedColumnName = "ID", unique = true)}) public Set<Address> getAddresses() { return _addresses; } /** * Set all the user's addresses. * * @param addresses all the user's addresses. * @return this user object */ protected User setAddresses(Set<Address> addresses) { this._addresses = addresses; return this; }
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.
The challenge is the group is from JSON representation. We cannot just build the backend in pure JPA representation. The JSON representation will need to expand to future security representation not limited to groups but something else.
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.
@wangf1122 - @josegar74 is suggesting that the json expression be replaced with a new pageGroup table that would be used to link the pages to the groups within the database. This will ensure that if a group or page is removed then the database will cascade the delete causing it to clean itself.
Otherwise with the json expression, there could be issues where it references groups that no longer exist.
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 have added the page/group joint table and the entity mapping. I got rid of the accessexpression JSON in this case. Please retest from your local.
…essExpression.java Co-authored-by: Jose García <[email protected]>
I see what you mean. I change the ui code from ng-click to ng-change. The javascript change will fit here better than click behavior |
….com/wangf1122/core-geonetwork into main.page.user.accessbility.enhanced
@@ -4,3 +4,13 @@ INSERT INTO Settings (name, value, datatype, position, internal) VALUES ('system | |||
|
|||
UPDATE Settings SET value='4.4.3' WHERE name='system/platform/version'; | |||
UPDATE Settings SET value='0' WHERE name='system/platform/subVersion'; | |||
|
|||
CREATE TABLE spg_page_group |
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.
@wangf1122
I'm not sure if create tables are required in the migration as I think JPA will take care of creating any missing tables.
@josegar74
Can you confirm if this is required?
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 had confirmed myself. It is not required. The JPA will automatically create the table. I will update the script.
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.
@wangf1122 I tested the feature and looks fine. The only thing that was that I could delete a group that had pages linked to it, the group in the page it's still there.
It can be good when removing the group to delete the relation or just show some message when deleting the group to inform that has static pages related and need to remove that relation first.
@@ -203,6 +227,30 @@ private ResponseEntity<Void> updatePageInternal(@NotNull String language, | |||
String newLabel = pageProperties.getLabel(); | |||
String newIcon = pageProperties.getIcon(); | |||
|
|||
Set<Group> _groups = new LinkedHashSet<>(); |
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 see this variable with the _groups
and another with the name groups
. I would rename them to have more meaningful names and remove the _
from this one.
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.
renamed to pageGroups. Please check
for (String groupName : pageProperties.getGroups()) { | ||
Group group = groupRepository.findByName(groupName); | ||
|
||
Group groupToAdd= new Group(); |
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.
What is the reason to do a copy of the group?
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 had trouble with the JPA not adding group if not doing copy. Cannot guarantee if the code will work without the copying
Co-authored-by: Jose García <[email protected]>
I have added the logic in group delete API to prevent the deletion if the group has associate with static pages. Similar logic like users and groups |
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 notice also issues when saving the pages:
- Create a page that has a status not related to groups.
- Edit it and change to related to groups and assign it to 1 group --> it works
- Edit it and change to related to groups and assign it to 2 group --> it doesn't work, it maintains the previous configuration. No error reported.
It seems happening also when creating a page assigned to 2 or more groups.
@@ -541,6 +547,21 @@ public void deleteGroup( | |||
)); | |||
} | |||
|
|||
List<Page> staticPages = pageRepository.findAll(); |
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 would add this method in the repository:
List<Page> findPageByStatus(Page.PageStatus status);
And update the code to the following to at least only process the pages that are assigned to groups:
List<Page> staticPages = pageRepository.findPageByStatus(Page.PageStatus.GROUPS);
List<Page> staticPagesAssignedToGroup =
staticPages.stream().filter(p ->
!p.getGroups().stream().filter(g -> g.getId() == groupIdentifier).collect(Collectors.toList()).isEmpty())
.collect(Collectors.toList());
if (!staticPagesAssignedToGroup.isEmpty()) {
throw new NotAllowedException(String.format(
"Group %s is associated with '%s' static page(s). Please remove the static page(s) associated with that group first.",
group.get().getName(), staticPagesAssignedToGroup.stream().map(p -> p.getLabel()).collect(Collectors.joining())
));
}
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 have added the code. Also the issue you are experiencing "Edit it and change to related to groups and assign it to 2 group --> it doesn't work, it maintains the previous configuration. No error reported." was due to the backend entity relation. It's supposed to be ManyToMany relation. Otherwise, the groupId in the spg_page_group table will be unique. So once one page occupied groupId_1, this groupId_1 will not be available to other pages. Once I have the ManyToMany relation, it does. Here is some example of my local database after the fix:
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.
Tested the latest changes and look ok.
The backport to
stderr
stdout
To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add .worktrees/backport-4.2.x 4.2.x
# Navigate to the new working tree
cd .worktrees/backport-4.2.x
# Create a new branch
git switch --create backport-7707-to-4.2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick 6d1fd4c5294d5398d49d96c535782cd3f08879b7,99e1e5486e83818aae6b8ce96efbbfcc23d14990,04a25216fe531dddfb50b6fc724f123f7f394923,214af08ef35cde02b1660b4c219c57da49216a80,e09d0c204a39ce58727ed6cffd5f2e037239853b,47a5ee200daf9a878d12cf85baf17e01a2d09727,db1b7db3c8c4cb97d487bf1498b6363cbd4afb3f,fd7c7b125de114437e02e7e27c02e799513d7967,c98548ab4325c20b528ae71eacd5d6b5738dc363,de04d9a052e450c653c6c052f8acdb49ab29001d,30a0b2b6597488b2af57f835c8962564e6d446bd,bc3ffb344b42190682cbc5c9abcb5a3fc487cad1,246b184e4fb3a7e5c55fdc334eff00a64936f0cb,8b10f742f2155d833f631f0beb86939f0ec3711b,864c2cbba01c5959e76c53bd4be063e7355cb4a9,a0a5534b18b8699e237efaadf636e375d2e4cbdd,7d8e03d18482180ef63181732dff3ad207b473bb,c93bade75516e2d6af099faab3171ebb662ceb61,7c056cf2c4f2b4e20ccd50faadbf57679b22b58b,9ca02c8784176e0f1c437b4a57ed109f2c0bf27d,262fa60115fe62817a1671d529bcd77f5430a25c,2d82af005440808ccbc3b23d3036fd4b350dcd81,56ac85c552ae4e2cf0ecb23b99915ad48e4d2730,292d127de196f944ef5ac29390c2141d1edc517c
# Push it to GitHub
git push --set-upstream origin backport-7707-to-4.2.x
# Go back to the original working tree
cd ../..
# Delete the working tree
git worktree remove .worktrees/backport-4.2.x Then, create a pull request where the |
* Add group/accessExpression field to static page feature * Filter none group member access to page belong to certain group * code improvement * multi selections for groups * multi selections for groups. * Refactoring group checking logic * Update services/src/main/java/org/fao/geonet/api/pages/model/GroupAccessExpression.java Co-authored-by: Jose García <[email protected]> * ui change menu behavior * Fixing ui issue * pageGroup joint relation in page entity * pageGroup joint relation in page entity (add SQL) * remove page creation script * Update domain/src/main/java/org/fao/geonet/domain/page/Page.java Co-authored-by: Jose García <[email protected]> * rename group * prevent group remove if it has association with static pages * JPA ManyToMany bug fix --------- Co-authored-by: Jose García <[email protected]>
* Add group/accessExpression field to static page feature * Filter none group member access to page belong to certain group * code improvement * multi selections for groups * multi selections for groups. * Refactoring group checking logic * Update services/src/main/java/org/fao/geonet/api/pages/model/GroupAccessExpression.java * ui change menu behavior * Fixing ui issue * pageGroup joint relation in page entity * pageGroup joint relation in page entity (add SQL) * remove page creation script * Update domain/src/main/java/org/fao/geonet/domain/page/Page.java * rename group * prevent group remove if it has association with static pages * JPA ManyToMany bug fix --------- Co-authored-by: Jose García <[email protected]>
This enhanced feature gives the administrative user the capability to config the static page to some specific user in some groups.
I have two static page, one for the "sandbox" or "my_org" group users. One for all logged users
Either the sandbox_editor or org_editor logged in, the "org" page will display:
But when the "other_editor who has no access to sandbox or my_org group logged in, this user cannot see "org" page
So this feature is fully expandable to some other security measure scenario because the backend table column is named as access expression and will store JSON string by parsing from Java object AccessExpression. We can customize it by change the java business model itself.