Enable option "Merge Liferay public pages" by default for all users - liferay

I'd like to know if there is a way to active the option "Merge Liferay public pages" by default for all the portal's user.
This option can be set here (have a look at the screenshot) :
Control panel > Personal site > Site Pages > Public Pages > Advanced.
I searched the portal properties options but didn't find anything.
If there is a way to set it through a hook, I'm also interested.

I found a solution.
I added a bit of code to my AutoLogin hook (see Liferay auto.login.hook property which can be set in the portail.properties file).
It's easy to set the "merge public page" option with the GroupServiceUtil class :
GroupServiceUtil.updateGroup(user.getGroupId(), "mergeGuestPublicPages=true");
If a "com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initi
alized" error is raised. It's necessary to first initialize the permission checker. Here is a way to do it:
Company company = PortalUtil.getCompany(request);
Role adminRole = RoleLocalServiceUtil.getRole(company.getCompanyId(),"Administrator");
List<User> adminUsers = UserLocalServiceUtil.getRoleUsers(adminRole.getRoleId());
PrincipalThreadLocal.setName(adminUsers.get(0).getUserId());
try {
PermissionChecker permissionChecker = PermissionCheckerFactoryUtil.create(adminUsers.get(0));
PermissionThreadLocal.setPermissionChecker(permissionChecker);
} catch (Exception e) {
e.printStackTrace();
}

Related

create setup form for custom module

I have a custom module getting executed right after the PDFGenerator finished. I followed this guide on how to create a custom module
https://stackoverflow.com/a/55799101/9945420
When processing a batch document I want to manipulate the generated PDF file and add a footer to that file. The content of that footer needs to get configured in the Administration module.
So within my project called "StampOnScanProcess" I added a Folder called "Setup" with two files. A Form called "FrmSetup"
public partial class FrmSetup : Form
{
private IBatchClass batchClass;
public FrmSetup()
{
InitializeComponent();
}
public DialogResult ShowDialog(IBatchClass batchClass)
{
this.batchClass = batchClass;
// Load previous Settings ...
return this.ShowDialog();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnSave_Click(object sender, EventArgs e)
{
// Save ...
this.Close();
}
}
and a UserControl called "UserCtrlSetup"
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISetupForm
{
[DispId(1)]
AdminApplication Application { set; }
[DispId(2)]
void ActionEvent(int EventNumber, object Argument, out int Cancel);
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId(CUSTOM_MODULE_NAME_SETUP)]
public partial class UserCtrlSetup : UserControl, ISetupForm
{
private const string CUSTOM_MODULE_NAME_SETUP = "StampOnScanProcess.Setup";
private AdminApplication adminApplication;
public AdminApplication Application
{
set
{
value.AddMenu(CUSTOM_MODULE_NAME_SETUP, CUSTOM_MODULE_NAME_SETUP, "BatchClass");
adminApplication = value;
}
}
public void ActionEvent(int EventNumber, object Argument, out int Cancel)
{
Cancel = 0;
if ((KfxOcxEvent)EventNumber == KfxOcxEvent.KfxOcxEventMenuClicked && (string)Argument == CUSTOM_MODULE_NAME_SETUP)
{
FrmSetup form = new FrmSetup();
form.ShowDialog(adminApplication.ActiveBatchClass);
}
}
}
I modified my registration file and added the setup form to it
[Modules]
StampOnScanProcess
[StampOnScanProcess]
RuntimeProgram=StampOnScanProcess.exe
ModuleID=StampOnScanProcess.exe
Description=...
Version=10.2
SupportsNonImageFiles=True
SupportsTableFields=True
SetupProgram=StampOnScanProcess.Setup
[Setup Programs]
StampOnScanProcess.Setup
[StampOnScanProcess.Setup]
Visible=0
OCXFile=StampOnScanProcess.exe
ProgID=StampOnScanProcess.Setup
When launching the Administration module I head over to the Batch Class Properties => Queues and want to call this setup form by clicking the Properties button in the middle.
Unfortunately the properties button is disabled so I can't open the setup form. This form gets added to the context menu of the batch class
How can I bind this form to the properties button instead? And what is the best way to store configured data and access it when the runtime application gets executed?
I need to think about how to store data because some users have user profiles
and the runtime application currently logs in with no credentials.
public void LoginToRuntimeSession()
{
login = new Login();
login.EnableSecurityBoost = true;
login.Login();
login.ApplicationName = CUSTOM_MODULE_ID;
login.Version = "1.0";
login.ValidateUser($"{CUSTOM_MODULE_ID}.exe", false, "", "");
session = login.RuntimeSession;
}
So it might happen that I have to store the credentials on setup too.
How can I bind this form to the properties button instead?
All interactions with menu entries are handled by ISetupForm.ActionEvent. New entries are added with the AddMenu method of the AdminApplication object. Kofax differentiates between multiple entries by name - imagine that you could have multiple menu entries at the same time, one on batch class level, another one on document class level, and another one in the ribbon - just to name a few examples. Kofax uses the same approach in any component that integrates into Administration (e.g. Custom Modules or Workflow Agents).
This is an example from one of our components. Note that three entries are added on BatchClass level and two more on DocumentClass level.
value.AddMenu("BatchClass.GeneralConfig", "Field Panel - General Configuration", "BatchClass");
value.AddMenu("BatchClass.FieldEditor", "Field Panel - Configure Batch Fields", "BatchClass");
value.AddMenu("DocumentClass.FieldEditor", "Field Panel - Configure Index Fields", "DocumentClass");
value.AddMenu("CopyBatchFieldConfig", "Field Panel - Copy Batch Field Configuration", "BatchClass");
value.AddMenu("PasteBatchFieldConfig", "Field Panel - Paste Batch Field Configuration", "BatchClass");
value.AddMenu("CopyIndexFieldConfig", "Field Panel - Copy Index Field Configuration", "DocumentClass");
value.AddMenu("PasteIndexFieldConfig", "Field Panel - Paste Index Field Configuration", "DocumentClass");
Each entry is no identified by its event text, the first parameter. For example, BatchClass.GeneralConfig is intended to open up a generic configuration dialog - on batch class level.
Now, back to our ActionEvent - this is how I distinguish between the entry selected by the user:
if ((KfxOcxEvent)EventNumber == KfxOcxEvent.KfxOcxEventMenuClicked)
{
AdminForm form = new AdminForm();
switch ((string)Argument)
{
case "BatchClass.GeneralConfig":
ConfigureGeneral(kcApp.ActiveBatchClass);
break;
[I] want to call this setup form by clicking the Properties button in
the middle.
I don't know if you can use this button - I would assume yes - yet personally I tend to put settings either on batch or document class level. For example - your PDF annotation settings may different from document class to class - having an entry on this level seems more natural.
And what is the best way to store configured data and access it when
the runtime application gets executed?
Custom Storage Strings, and you can let your imagination run wild here. The most simplistic approach is to store key-value pairs during setup, and retrieve them in runtime. Here's a generic call (BatchClass is an IBatchClass object, i.e. a pointer to the ActiveBatchClass property of the AdminApplication object):
// set a CSS
BatchClass.set_CustomStorageString(name, value);
// get a CSS
BatchClass.get_CustomStorageString(name)
I usually use a single custom storage string only and store custom object - the object is a base64-encoded serialized XML using XmlSerializer - but again, that's up to you. The only recommendation is to rely on CSS only - don't use external files to store configuration parameters. A CSS is an integral part of your batch class - so, when exporting said class and importing it on a different system, your entire configuration will be there.
I need to think about how to store data because some users have user
profiles
Usually, you don't need to worry about that. The properties for user and password in ValidateUser are entirely optional - and since you're planning to write an unattended module - ideally a Windows Service, credentials should be maintained there. Kofax and Windows would automatically make sure the credentials are passed on, and your module will run under this user's context. Just make sure the user has permissions for the module and all associated batch classes. It's different if you're planning to write an attended module, for example an enhanced Validation module.

VSTO-Excel Custom Task Pane AutoResize based on Screen Resolution

I have a problem with my VSTO addin for excel.
I tried creating custom task pane fot my addin. However, when I tried to deploy it on a screen with different resolution from the developer's monitor, the addin does not automatically fits the screen. Note: my clients have different screen resolution.
On my vsto project, i tried to create a custom user control, and attach it on the excel pane.
Please see my code below:
private void btnDownload_Click(object sender, RibbonControlEventArgs e)
{
taskPaneView = new ucCusipAddPanel();
if (myTaskPane == null)
{
myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(taskPaneView, "My Custom Task Pane");
myTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
myTaskPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
myTaskPane.Visible = true;
myTaskPane.Width = 303;
}
else
{
myTaskPane.Visible = true;
taskPaneView.BringToFront();
taskPaneView.Focus();
}
}
ucCusipAddPanel is the name of my user control.
This is how invoke my custom taskpane upon ribbon button click. I already set the AutoSize property to true of my user control however still the problem exists.
How could I resolve this?
Thank you in advance.
You need to play with the AutoScaleMode of the myTaskPane object.
I think the correct solution is to use: myTaskPane.AutoScaleMode = AutoScaleMode.Dpi;
see MSDN

Cannot save all of the property settings for this Web Part - Sharepoint

"Cannot save all of the property settings for this Web Part. The
default namespace "http://schemas.microsoft.com/WebPart/v2" is a
reserved namespace for base Web Part properties. Custom Web Part
properties require a unique namespace (specified through an
XmlElementAttribute on the property, or an XmlRootAttribute on the
class)."
No where do I get help regarding this error.
This is when adding custom properties to my webpart, why cant I save the properties when I edit my webpart and click on save/apply? (then I get that error)
Code--
[DefaultProperty("Text"), ToolboxData("<{0}:CustomPropertyWebPart runat=server></{0}:CustomPropertyWebPart>"),
XmlRoot(Namespace = "ExecuteStoreProc")]
public class CustomPropertyWebPart : Microsoft.SharePoint.WebPartPages.WebPart
{
const string c_MyStringDefault = "Sample String";
}
// Create a custom category in the property sheet.
[Category("Custom Properties")]
// Assign the default value.
[DefaultValue(c_MyStringDefault)]
// Property is available in both Personalization
// and Customization mode.
[WebPartStorage(Storage.Personal)]
// The caption that appears in the property sheet.
[FriendlyNameAttribute("Custom String")]
// The tool tip that appears when pausing the mouse pointer over
// the friendly name in the property pane.
[Description("Type a string value.")]
// Display the property in the property pane.
[Browsable(true)]
[XmlElement(ElementName = "MyString")]
// The accessor for this property.
public string MyString
{
get
{
return _myString;
}
set
{
_myString = value;
}
}
Can you try going to Site Settings > Galleries > Web Part > New
In that window, put a checkbox next to the webpart you are trying to add, then click Populate
If its populate correctly then it is working otherwise there is some error in the webpart.
Return to your webpage where you want to add the webpart, try to add the webpart by selecting it in the gallery.
If this works (you were able to add it to your page), you can open the webpart added in your webpart gallery (Site Settings > Galleries > Web Part) and compare it to your own .dwp file to see what you did wrong.
Hope this helps

SharePoint 2010: Disable / Hide references to SPSDisco.aspx

After upgrading some of our external websites running on SharePoint 2007 to 2010, we ran a link checker to find problems. We noticed the log showed requests for a file called spsdisco.aspx. Indeed, when examining the source of our web pages, SharePoint is adding the following link element to the page HEAD:
<link href="_vti_bin/spsdisco.aspx" rel="alternate" type="text/xml" />
This is a web service discovery file listing out the names and locations of all of SharePoint's web service endpoints. Even worse, this file is starting to show up in search indexes. At best it is embarrassing; at worst it's a potential vulnerability (these are external websites). Because it's a virtual file, it shows up under every site and subsite, so a manual approach to "hiding" each one is difficult and clumsy.
I can't seem to find any actual documentation about it -- a few references on updating it to include a custom web service, but that's about it. How might we approach a reliable, top-down approach to disabling access to these pages? I think we can find a way to suppress the LINK element in the page, but that's just obscuring the problem.
Is there a location in SharePoint (Site or Central Admin) to turn it off? Would you just add some request filtering to IIS to disallow access to SPSdisco.aspx and the ASMX files?
Update: On Kev's suggestion, I've cross-posted to sharepoint.stackexchange.com.
Update 2: See, I hadn't abandoned this question. We finally had time to get some MS guidance and build a deployable SharePoint solution to address the issue.
As a quick fix I would add a request filtering rule to deny access to SPSDisco.aspx.
But you might want to ask on the new SharePoint Stack Exchange site about a more robust fix:
https://sharepoint.stackexchange.com/
Here is the solution that we arrived at. It was in part based on recommendations by our Microsoft representative, so you might consider this an unofficial, "official" approach.
First, we need keep SharePoint from advertising the disco file to the world (i.e. Google). Simply remove the following line in your master pages:
<SharePoint:SoapDiscoveryLink runat="server"/>
This will suppress the <link href="/_vti_bin/spsdisco.aspx" rel="alternate" type="text/xml"> reference in the HEAD of your pages.
Next, we want to make sure that unauthorized users don't have access to the web services described by the disco file, or anything in _vti_bin for that matter. If your site only runs internal to your firewall (an intranet, for example), then this isn't as important. But if you've got anonymous endpoints that can be accessed externally, you want them locked down.
This is an excellent application for an HttpModule. We'll build one that intercepts any request containing _vti_bin in the path, and if the current user is unauthorized will return a 404 NOT FOUND status code. I chose to return a 404 rather than a 401 UNAUTHORIZED because I don't just want to lock those paths down, I want to hide the fact that anything even exists at those paths.
Our HttpModule looks like this:
using System;
using System.Web;
namespace Custom.SharePoint.HttpModule.SpSecureVtiBin {
public class SpSecureVtiBinModule : IHttpModule {
#region IHttpModule Members
public void Dispose() { }
public void Init( HttpApplication context ) {
context.AuthorizeRequest += new EventHandler( context_AuthorizeRequest );
}
protected virtual void context_AuthorizeRequest( object sender, EventArgs e ) {
HttpApplication app = (HttpApplication)sender;
string requestedPath = app.Request.Path;
if ( requestedPath.ToLowerInvariant().Contains( "_vti_bin" ) ) {
if ( !app.Request.IsAuthenticated ) {
app.Response.StatusCode = 404;
app.Response.StatusDescription = "Not Found";
app.Response.Write( "404 NOT FOUND" );
app.Response.End();
}
}
}
#endregion
}
}
Simple enough. To use the HttpModule, it needs to be registered in the site's web.config file with an entry under \configuration\system.webServer\modules:
<add name="SpSecureVtiBinModule" type="Custom.SharePoint.HttpModule.SpSecureVtiBin.SpSecureVtiBinModule, Custom.SharePoint.HttpModule.SpSecureVtiBin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[your_public_key_token]" />
Of course, we don't want to modify a SharePoint application's web.config file manually. We'll create an SPFeatureReceiver to do the job:
using System.Collections.ObjectModel;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace Custom.SharePoint.HttpModule.SpSecureVtiBin {
public class ModuleFeatureReceiver : SPFeatureReceiver {
private static string _owner = "SpSecureVtiBinModule";
public override void FeatureActivated( SPFeatureReceiverProperties properties ) {
SPWebApplication app = (SPWebApplication)properties.Feature.Parent;
app.WebConfigModifications.Add( GetModificationForSystemWebServer() );
app.WebService.ApplyWebConfigModifications();
app.Update();
}
public override void FeatureDeactivating( SPFeatureReceiverProperties properties ) {
SPWebApplication app = (SPWebApplication)properties.Feature.Parent;
Collection<SPWebConfigModification> mods = app.WebConfigModifications;
int modCount = mods.Count;
bool modRemoved = false;
for ( int i = modCount - 1; i >= 0; i-- ) {
SPWebConfigModification mod = mods[i];
if ( mod.Owner.Equals( _owner ) || mod.Owner.Equals( "CHK.SharePoint.HttpModule.SpSecureVtiBin.SpSecureVtiBinModule" ) ) {
app.WebConfigModifications.Remove( mod );
modRemoved = true;
}
}
if ( modRemoved ) {
app.WebService.ApplyWebConfigModifications();
app.Update();
}
}
private SPWebConfigModification GetModificationForSystemWebServer() {
return new SPWebConfigModification {
Name = "add[#name='SpSecureVtiBinModule']",
Owner = _owner,
Path = "configuration/system.webServer/modules",
Value = #"<add name=""SpSecureVtiBinModule"" type=""Custom.SharePoint.HttpModule.SpSecureVtiBin.SpSecureVtiBinModule, Custom.SharePoint.HttpModule.SpSecureVtiBin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[your_public_key_token]"" />",
Sequence = 0
};
}
}
}
Now all that's left is to package up the HttpModule. You'll need to define a Feature in the package and reference the SPFeatureReceiver class. This will cause the web.config entry to be added when the Feature is activated, and the entry to be removed when the Feature is deactivated. Target the Feature for a WebApplication and the assembly deployment target to GlobalAssemblyCache.

Sharepoint : Access denied when editing a page (because of page layout) or list item

I'm logged in as the System Account, so it's probably not a "real access denied"!
What I've done :
- A custom master page
- A custom page layout from a custom content type (with custom fields)
If I add a custom field (aka "content field" in the tools in SPD) in my page layout, I get an access denied when I try to edit a page that comes from that page layout.
So, for example, if I add in my page layout this line in a "asp:content" tag :
I get an access denied. If I remove it, everyting is fine. (the field "test" is a field that comes from the content type).
Any idea?
UPDATE
Well, I tried in a blank site and it worked fine, so there must be something wrong with my web application :(
UPDATE #2
Looks like this line in the master page gives me the access denied :
<SharePoint:DelegateControl runat="server" ControlId="PublishingConsole" Visible="false"
PrefixHtml="<tr><td colspan="0" id="mpdmconsole" class="s2i-consolemptablerow">"
SuffixHtml="</td></tr>"></SharePoint:DelegateControl>
UPDATE #3
I Found http://odole.wordpress.com/2009/01/30/access-denied-error-message-while-editing-properties-of-any-document-in-a-moss-document-library/
Looks like a similar issue. But our Sharepoint versions are with the latest updates. I'll try to use the code that's supposed to fix the lists and post another update.
** UPDATE #4**
OK... I tried the code that I found on the page above (see link) and it seems to fix the thing. I haven't tested the solution at 100% but so far, so good. Here's the code I made for a feature receiver (I used the code posted from the link above) :
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Xml;
namespace MyWebsite.FixAccessDenied
{
class FixAccessDenied : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
FixWebField(SPContext.Current.Web);
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
static void FixWebField(SPWeb currentWeb)
{
string RenderXMLPattenAttribute = "RenderXMLUsingPattern";
SPSite site = new SPSite(currentWeb.Url);
SPWeb web = site.OpenWeb();
web.AllowUnsafeUpdates = true;
web.Update();
SPField f = web.Fields.GetFieldByInternalName("PermMask");
string s = f.SchemaXml;
Console.WriteLine("schemaXml before: " + s);
XmlDocument xd = new XmlDocument();
xd.LoadXml(s);
XmlElement xe = xd.DocumentElement;
if (xe.Attributes[RenderXMLPattenAttribute] == null)
{
XmlAttribute attr = xd.CreateAttribute(RenderXMLPattenAttribute);
attr.Value = "TRUE";
xe.Attributes.Append(attr);
}
string strXml = xe.OuterXml;
Console.WriteLine("schemaXml after: " + strXml);
f.SchemaXml = strXml;
foreach (SPWeb sites in site.AllWebs)
{
FixField(sites.Url);
}
}
static void FixField(string weburl)
{
string RenderXMLPattenAttribute = "RenderXMLUsingPattern";
SPSite site = new SPSite(weburl);
SPWeb web = site.OpenWeb();
web.AllowUnsafeUpdates = true;
web.Update();
System.Collections.Generic.IList<Guid> guidArrayList = new System.Collections.Generic.List<Guid>();
foreach (SPList list in web.Lists)
{
guidArrayList.Add(list.ID);
}
foreach (Guid guid in guidArrayList)
{
SPList list = web.Lists[guid];
SPField f = list.Fields.GetFieldByInternalName("PermMask");
string s = f.SchemaXml;
Console.WriteLine("schemaXml before: " + s);
XmlDocument xd = new XmlDocument();
xd.LoadXml(s);
XmlElement xe = xd.DocumentElement;
if (xe.Attributes[RenderXMLPattenAttribute] == null)
{
XmlAttribute attr = xd.CreateAttribute(RenderXMLPattenAttribute);
attr.Value = "TRUE";
xe.Attributes.Append(attr);
}
string strXml = xe.OuterXml;
Console.WriteLine("schemaXml after: " + strXml);
f.SchemaXml = strXml;
}
}
}
}
Just put that code as a Feature Receiver, and activate it at the root site, it should loop trough all the subsites and fix the lists.
SUMMARY
You get an ACCESS DENIED when editing a PAGE or an ITEM
You still get the error even if you're logged in as the Super Admin of the f****in world (sorry, I spent 3 days on that bug)
For me, it happened after an import from another site definition (a cmp file)
Actually, it's supposed to be a known bug and it's supposed to be fixed since February 2009, but it looks like it's not.
The code I posted above should fix the thing.
Try to publish your MasterPage and Page Layouts, this is the most common reason. Since the system account is godmode, it wont get that error.
In SharePoint Designer you cannot do the last step in the publishing workflow (Approval), so you:
SharePoint Designer:
CheckIn => Publish Major Version, hit the OK button or go to /_catalogs/masterpage on the site .
Then and use the Context Menu to Approve the MasterPage and Layouts.
Some ideas:
Check if any web parts in your custom Page Layout and Master Page are not registered as safe.
Did you define your own custom field type, like write a class which extends SPField? If so, are you using a custom Field Control? If you are, check if it is doing anything which may need elevated privileges.
Likewise, check for any edit mode panels containing web parts of web controls which might be trying to do something which needs elevated privileges.
See the code I've posted in the edit of the post. It fixed my problem.
The problem appears to be caused by an error in the stsadm -o export function in certain versions of SharePoint (I got it doing an export from a 2007 RTM MOSS server). Importing the bogus export file causes the "edit-denied-access" problem in all NEWLY-CREATED lists. The patches for later version from Microsoft fix stsadm -o export, but DO NOT FIX the broken lists; that requires a procedure like tinky05's.

Resources