Our company is using Liferay portal 6.0.5 CE.
Within liferay we have a Community, community has few members and few web-contents.
By default all members have role Community member and they can view these web-contents. But if user tries to search web content via liferay search, it does not provide any results.
If I set permissions for web-contents such that Guest role can also view, then search provides the relevant results.
If it matters, before we had a Liferay 5.x and have migrated to 6.0 & then to 6.0.5.
Any ideas for this?
Thanks.
It seems that the guest view permissions for articles have not been set when migrating from 5.0 (if at all permissions have been set before for guest users). Easy fix would be assigning guest view permissions for all the articles that you want to make visible for guest in the respective community. this line in the below code assigns view permissions
JournalArticleLocalServiceUtil.addArticleResources(groupId,
article.getArticleId(), new String[] { "VIEW" },
new String[] { "VIEW" });
its been referred as resource and you will be adding permissions to the Article Resources.
ThemeDisplay themeDisplay = (ThemeDisplay) request
.getAttribute(WebKeys.THEME_DISPLAY);
long groupId = themeDisplay.getLayout().getGroupId();
List<JournalArticle> articles = JournalArticleLocalServiceUtil
.getArticles(groupId);
for (JournalArticle article : articles) {
JournalArticleLocalServiceUtil.addArticleResources(groupId,
article.getArticleId(), new String[] { "VIEW" },
new String[] { "VIEW" });
}
Thank you for advice, but I solved this trouble via hook for search portlet. For searching I used DynamicQuery and PermissionChecker and simple method String.contains(). It works bit slower, but it works--at least for 1k+ web contents!
Related
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);
I haven't found that much information online about how to utilize the Social Part of SharePoint 2013 by Server Object Model. To understand and follow my question better i recommend you going to this site.
Lets say I have a Feature Receiver that is fired when i certain site is created and I would like to take advantage of the Follow Content Feature but instead of every time a site is created i would like to make the person that created the site automatically follow that site.
Does anyone got experience with working with the Social functionallity in SharePoint 2013? If so would be awesome with a summary how to use the different Social methods.
Social Actor
From what I've understood from reading about this you need to create a "Actor" to represent the item or in my case the site. SocialActorInfo which takes to properties ContentUri and ActorType.
SocialActorInfo actorInfo = new SocialActorInfo();
actorInfo.ContentUri = contentUrl;
actorInfo.ActorType = contentType;
Find and Check if that Actor is followed by the current user
Then you have to check if that SocialActor is Followed by the current user.
ClientResult<bool> isFollowed = followingManager.IsFollowed(actorInfo);
Follow/Unfollow the Site/Item
ClientResult<SocialFollowResult> result = followingManager.Follow(actorInfo);
clientContext.ExecuteQuery();
"followingManager.UnFollow(actorInfo);"
Questions,
If I want to follow a site, what kind of ActorTypes are there?
How do i do this with server-side code?
Additional Information
Microsoft says: When users follow documents, sites, or tags, status updates from documents, conversations on sites, and notifications of tag use show up in their newsfeed. The features related to following content can be seen on the Newsfeed and the Following content pages.
SharePoint Server 2013 provides the following APIs that you can use to programmatically follow content:
Client object models for managed code
NET client object model
Silverlight client object model
Mobile client object model
JavaScript object model
Representational State Transfer (REST) service
Server object model
Link to Follow Content in SharePoint 2013, I can just find how to do it with REST or CSOM.
Just wanted to Share, this Solved the task.
Just a Follow Method that takes a SPWeb object and a SPUser object.
SPServiceContext serverContext = SPServiceContext.GetContext(web.Site);
UserProfileManager profileManager = new UserProfileManager(serverContext);
string userString = user.LoginName.ToString();
UserProfile userProfile = profileManager.GetUserProfile(userString);
if (userProfile != null)
{
SPSocialFollowingManager manager = new
SPSocialFollowingManager(userProfile);
SPSocialActorInfo actorInfo = new SPSocialActorInfo();
actorInfo.ContentUri = new Uri(web.Url);
actorInfo.AccountName = user.LoginName;
actorInfo.ActorType = SPSocialActorType.Site;
manager.Follow(actorInfo);
}
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.
I have a SharePoint 2010 MySites set up on its own web application. There is the standard site collection at the base level, http://site:80/.
The personal sites for each user is at the managed URL /personal/.
I have a working event handler which add items to the Newsfeed when a user adds something to a picture library.
THE PROBLEM:
The problem is, this only works if they add to a picture library at the base site collection, http://site:80/, and does NOT work if they add to http://site:80/personal/last first/.
Does anyone know why? The event handler feature is site scoped and my understanding is that it should work on all subsites.
The problem is that personal sites are not subsites of My Site host. In fact each user's personal site is a site collection on its own. So basically you need to register your event receiver not only for My SIte host, but also for each user's personal site.
Ok. Because you can only 'staple' features to site definitions which will be provisioned in the future, you need a way to activate new features on existing sites.
So, the fix I discovered and used follows:
The default page for the newsfeed is http://site:80/default.aspx. If you create an event receiver and scope it for 'site' and deploy it globally or to that web application, then it will work on the base site collection. Each personal site is a site collection and has the feature but it needs to be activated on each personal site collection.
So, in the default.aspx page, you place the following which will activate the feature if it has not yet been activated.
<script runat="server" type="text/c#">
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
String sAccount = (((SPWeb)((SPSite)SPContext.Current.Site).OpenWeb()).CurrentUser.LoginName).Split('\\')[1];
String basePersonalURL = "http://site:80/personal/";
String eventReceiverFeatureId = "12345678-1234-1234-1234-1234567890ab";
using(SPSite site = new SPSite(basePersonalURL + sAccount)) {
site.AllowUnsafeUpdates = true;
using(SPWeb web = site.RootWeb) {
web.AllowUnsafeUpdates = true;
try { site.Features.Add(new Guid(eventReceiverFeatureId)); } catch {}
web.AllowUnsafeUpdates = false;
}
site.AllowUnsafeUpdates = false;
}
}
</script>
You also need to edit the web.config file in order to allow inline code to run for this page. Hope this helps.
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);