Multiple database application ACL (part 2) - xpages

I posted this question Access Control with a multi database application
So I tried putting it into application. Here is the case. I have a mainDB that has an ACL with no roles defined. The User clicks a button and it opens a control for CRUD with a datasource that has a computed filepath to a different database call it appDB. In appDB the ACL has several roles defined, and I have added myself to the ACL and assigned me the roles [Admin] and [Finance]. In this control I have added an After Page Load event that does the following:
var roles = context.getUser().getRoles();
viewScope.put("vsRoles", roles);
Upon opening the page the viewScope vsRoles is [] so it has not recognized that I have an additional set of roles in the appDB. So it would appear that context.getUser().getRoles() only gets my roles at authentication time when I log into the mainDB.nsf, and is not picking up the roles when I open appDB. I need to use the roles to configure what actions a person can perform, plus which documents a user can read and/or edit.
To complicate the issue the user may switch between multiple target application databases and will no doubt have different roles and access to each one.
thanks for the response to my previous question,but I might not have explained it in enough detail.

So, as far as I understood, what you need is to learn what specific roles the user has for the appDb.
context.getUser().getRoles() provides information about the current application (mainDB.nsf in your case). You are accessing appDB.nsf at a data source level. You can use a java method to learn the roles of a specific user in a target database:
public static List<String> getRoles(Database targetDb, String userName) {
ACL acl=null;
List<String> roles=new ArrayList<String>();
try {
acl=targetDb.getACL();
roles.addAll(targetDb.queryAccessRoles(userName));
} catch (NotesException e) {
// failed, nothing to do...
} finally {
if(acl!=null) acl.recycle();
}
return roles;
}
As an example:
Session session=ExtLibUtil.getCurrentSession();
Database appDb=session.getDatabase("", "appdb.nsf");
// Make sure appDb is not null...
List<String> roleList=getRoles(appDb, session.getEffectiveUserName());
ExtLibUtil.getViewScope().put("vsRoles", roleList);

Related

Checking roles from some group Micronaut Security

There is a controller with an edit object endpoint.
#Secured(SecurityRule.IS_AUTHENTICATED)
public class Controller
#PUT
#Secured(MODIFY) // Security Mapping for requests
public CompletableFuture<ModifyResponse> update(#NotBlank List<String> list,
#RequestContext UserContext context){
return super.update(storage.schema(), list, context);
}
As you can see now - any authorized user can edit the object.
We need to implement role validation from a user group, but each object has its own validation group. What tools to use to implement this functionality?
I was thinking of just storing the desired roles in the object and pulling them out for validation.
If you can, provide examples with detailed descriptions of the tools used, as I'm a young developer and it's still hard to implement everything myself.
Thanks in advance!

setCanDeleteDocuments() Lotus Notes ACL

I am trying to delete document,where conditions is...
Where the user is in Group and having the deletion rights & every users in group is able to delete the document.
But problem is when, If the name I specify is also listed explicitly in the ACL and does not have deletion rights.Then it does not check the group rights which is fair enough.
For that i am trying to give deletion rights to those users who are in group by code given below.
var acl:NotesACL=database.getACL();
var entry:NotesACLEntry=acl.getFirstEntry();
if(entry!=null)
{
var user:NotesACLEntry=acl.getEntry(#UserName());
if(user.isCanDeleteDocuments()==false)
{
user.setCanDeleteDocuments(true);
acl.save();
}
}
Where it shows error like,
Exception occurred calling method NotesACL.save() null.
Even explicitly added user is having user type=person & Access= Manager in ACL.
is there any other way to do this?
Any help would be appreciated.
Thanks in advance.
Using database as a starting point means you're getting the database as the user. Unless the user already has Manager access to the database, this will fail because the user doesn't have access to update the ACL.
You can use sessionAsSigner, but bear in mind you cannot use the getCurrentDatabase() method. Instead you must use the getDatabase(server,filePath) method in order to get the database with the signer authority. Obviously the signer also needs rights to modify the ACL.

Logged in user can only access 1 page?

Using Orchard 1.6 Iv created a new role 'FactoryWorker'. When this user logs in from the front end I want them to be navigated to one page only.
OrchardLocal/System/ManufacturedProducts
I have set this page to be a print screen of the order details so the factory worker will know what products to get ready for ship out & they wont be able to navigate as no menu appears, but also need the other pages blocked incase the user decides to enter the URL of a page they arnt allowed access to.
This is the only page I want this particular user to be able to access(after they login), and I have added a logout button, which logs out the user and returns them to the home page.
So iv been looking through editing a role, with permissions and content etc...but this all seems to be applying to forms and content in general. where the user can access any content type etc...
So can someone advise me on how to do this?
thanks for any replies
UPDATE
I forgot to mention that this is not a content type, item or part I am talking about.
I have created my own controller & View & VM which is accessible from the dash board (using the AdminMenu, which brings the admin user to OrchardLocal/System/ManufacturedProducts)
I have looked at Orchard.ContentPermissions Feature but it only seems to allow me to 1)Grant permissions for others or 2)Grant permission for own content
any ideas?
You can use a Request Filter, (I do not know if it is the best way) :
FilterProvider – defines the filter applied to each request. Resembles the way default ASP.NET MVC action filters work with the difference that it’s not an attribute. All FilterProvider objects are injected into the request pipeline and are applied to all requests (so you need to check if the current request is suitable for your filter at the beginning of an appropriate method).
From : http://www.szmyd.com.pl/blog/most-useful-orchard-extension-points
So you could implement something like this
public class Filter : FilterProvider, IAuthorizationFilter {
private readonly IAuthenticationService _authenticationService;
public Filter(IAuthenticationService authenticationService) {
_authenticationService = authenticationService;
}
public void OnAuthorization(AuthorizationContext filterContext) {
//If route is the restricted one
if (filterContext.HttpContext.Request.Url.AbsoluteUri.Contains("OrchardLocal/System/ManufacturedProducts")) {
//Get the logged user
IUser loggedUser = _authenticationService.GetAuthenticatedUser();
if (loggedUser == null)
return filterContext.Result = new HttpUnauthorizedResult();
//Get the Roles
var roles = loggedUser.As<IUserRoles>().Roles;
if (!roles.Contains("FactoryUser")) {
//User is not authorized
return filterContext.Result = new HttpUnauthorizedResult();
}
}
}
}
Note: Untested code!
EDIT: Also you could invert the logic and check if the logged user has the role 'FactoryUser' and restrict its access to every page except the one they should see.
Your module can create a new permission (look at one of the permissions.cs files for examples), then create a role that has only that permission. Have your controller action check that permission (again, many examples found by finding usage of the permissions defined in one of the permissions.cs).
You can use the Content Permissions module. Using this module you can attach a content item permission part to a content type. This part allows you to choose which roles can see the content when you create it.

JSF Redirect page based on User role

I have two types of admin.
Super admin and normal admin.
Both start on the page admin.xhtml.
I want to forward super admin users to super-admin.xhtml and normal admin to normal-admin.xhtml.
How do I do this in JSF (I'm using Spring Security)?
I'm unfamiliar with JSF, but assuming it functions under the hood just like a Spring MVC JSP application, you can have your controller deliver a different page depending on the role(s) held by the user:
#RequestMapping("/admin.xhtml")
#PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_SUPERADMIN')")
public String getAdminPage(Modelmap model, Principal principal) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
for (GrantedAuthority authority : authorities) {
if (authority.toString() == "ROLE_SUPERADMIN") { return "superadminpage"; }
}
//no need to check for admin privileges, since the annotation took care of that
//if you're not using annotations (or #PostAuthorize), you'd have to capture the
//'admin' role as well, and adjust the return statements accordingly.
return "adminpage";
}

Accessing the user from a liferay portlet?

I'm attempting to develop a portlet for liferay.
How can I get access to the username and password (and other data liferay has) of the user that's currently logged in?
I'd also like to be able to execute some code when users change their password.
You can get the User ID by calling getRemoteUser() in the PortletRequest object. This is defined by JSR-168 therefore it's cross-portal compatible.
Once you have the ID you can fetch the additional informations by calling getUserById() (a Liferay specific service). This is something not covered by Portlet API specification, so it locks you to the Liferay.
Liferay Specific stuff, here is a code sample to be written in your Portlet Class to retrieve the User:
ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
User user = themeDisplay.getRealUser(); // it gives you the actual Logged in User
//you can also use
// User user = themeDisplay.getUser(); // this would fetch the User you are impersonating
long userId = user.getUserId();
String userName = user.getEmailAddress();
Alternatively;
long userId = themeDisplay.getRealUserId(); // themeDisplay.getUserId();
User user = UserLocalServiceUtil.getUser(userId);
Impersonate User:
Liferay has a concept that admins (or persons with the correct set of permissions) can impersonate a particular user of the portal. Through this they can see how the portal looks to that user.
For executing the code when user change their passwords:
One approach would be to create a hook plugin and overriding the services by extending the UserLocalServiceWrapper class. Then checking for the password change and executing your code inside the your custom class.
Hope this helps.
Or you can just use javascript:
Liferay.ThemeDisplay.getUserId()
There are many nice to haves in the Liferay namespace, take a look at the not so well documented API:
https://www.liferay.com/community/wiki/-/wiki/Main/Liferay+JavaScript+API
https://www.liferay.com/web/pankaj.kathiriya/blog/-/blogs/usage-of-liferay-js-object
Also, take a look at the web services available under localhost:8080/api/jsonws which you can invoke with a javascript call:
Liferay.Service(
'/user/get-user-by-id',
{
userId: 10199
},
function(obj) {
console.log(obj);
}
);
One simple and easy way to get the user in Liferay is PortalUtil.getUser function.
User user = PortalUtil.getUser(portletRequest);

Resources