Modx - Multiple contexts on one domain - modx

I've a Modx site running. Now i want to get some resources like modx-generated javascript files. It is possible to put these in the web context, but than it can be seen by all users.
So i created a new context named "Resources" (key: res), gave it Load-Only permissions and created a resource in it. I've also initialize it in the index.php file:
$modx->initialize('web');
$modx->initialize('res');
But when i try to access the resource, it doesn't work.
Did i missed something?

Calling modX::initialize() twice will not work as it checks for state.
Either remove the first call to initailise the web state or write a plugin and use modX::switchContext()

Related

Public Google Apps Script - how can I make my API key hidden but still retrieve it?

I have a script that retrieves a webhook (meaning it has to be deployed as a publicly accessible App), and then uses an API to send a message.
The API requires using a key and secret, which I obviously don't want accessible to the public.
Q1: Is there a way to hide an API key/secret in another script and somehow have it accessible?
(Or any other similar solution - doesn't have to be fancy, just functional/safe).
Alternate Question:
Q2: What can a stranger actually see in my public Apps Script project? The full code? If I hide keys in a functions with an underscore ie. function name_(){}, can they read it?
IMPORTANT INFO: I have not 'shared' the project or spreadsheets with anyone, they're still private. But I've 'deployed' the Web App with permissions for 'anyone'. I assume that means anyone can access?
Everything in the script is visible to whoever has access (script owner, workspace admins, added users). Unless only the url of the webapp is shared and if the script itself is not shared then they are not able to access the script, so technically you can still keep them in your script. It is safe there and only the owner and workspace admins (if it is for Google workspace) can access it.
A way you can store/save the key is by storing it in script properties. Doing this you only need to run the script once to store the API key, moving forward you can remove the API key from the script and it will still run:
https://developers.google.com/apps-script/guides/properties#saving_data
Also refer to this post for more information, in my posted answer I have also provided alternatives and reference links:
Is it safe to put in secrets inside Google App Script code?
My project meet this issue, too. Because the amount of functions is not too much , So i hide my main GAS behind an dummy one .
So far I had 2 GAS
the main GAS with key , and all functions , and I deploy it as Web APP
Of cause u need doGet or doPost to do as entrance of API
The dummy one to share with users.
Then you can call something like below in dummy GAS
var url = 'https://script.google.com/macros/s/xxxxxxxxxxx/exec';
UrlFetchApp.fetch(url,{'method': 'get'});
I hope its useful in your case.

The terms of use URL, /portal/terms_of_use is not working - I get a requested resource could not be found error

I have configured my Liferay 7 site with a terms of use web content document. It works perfectly when new users log in for the first time.
However, I need to be able to provide a link to review the terms of use. The only thing I see is in the Liferay Portal struts-config.xml file, which is "/portal/terms_of_use". But this link appended to my hostname is not working. I get a "Not Found" error page ("The requested resource could not be found.").
Am I using the wrong URL? I've tried searching for what the URL would be and have not found anything, which is surprising since I would think this is a common requirement.
With the routing of web-stuff to OSGi bundles, there's no longer any top-level URL that can be specified this way (there may never have been one). However, there is a way to get to it:
http://localhost:8080/c/portal/terms_of_use requires login, but results in the (in my case unconfigured) terms of use. The /c within the URL targets struts (and maybe something else - the /portal within targets a certain bundle (portal-web in this case)

Script file file not being loaded through ScriptLink custom action

I am having trouble with script link custom actions. I am building a SharePoint app, and I successfully added a site-scope custom action pointing to a script file in the Style Library, as I want this particular script to be injected to all the pages of my SharePoint site.
While it works in certain situations, the script link injection breaks without apparent reason under certain conditions. For example, when I arrive on my root web, the script will be injected. But, if I go to a certain link within this web (for example Home or Site Contents), the file that is supposed to be injected will simply not be fetched from the Style Library and therefore never be injected, resulting in an uncaught ReferenceError when I try to call one of the script's function. The weirdest part is that a page refresh through Ctrl+F5 will fetch the script file without any problem, regardless of the page's ability to originally fetch the script file when first accessed. It will keep the script until it is accessed through a link again.
I've read up on Sharepoint caching, thinking it may be the cause of my problem, but the trouble is that these articles mostly talk about cache-induced errors when updating a file, while I am only trying to access it.
One thing to note is that, due to limitations, I am adding the script link custom action through code. Here's an example of what this kind of call currently looks like in my app:
context.Load(context.Site.UserCustomActions);
context.ExecuteQuery();
customAction.Name = "MyScriptLink";
customAction.Location = "ScriptLink";
customAction.Sequence = 100;
customAction.ScriptSrc = "~SiteCollection/Style Library/MySite/MyScript.js";
customAction.Update();
context.ExecuteQuery();
So, what's going on here ? Why is my script no injected on certain pages ? Why does a refresh on these exact same pages manage to fetch the file without any problem ?
Found it ! Three words: Minimum Download Strategy. Disable it, it messes with you page redirect behavior within a SharePoint site (either through code or through site settings)
Edit: If you still want MDS enabled on your site, there is a solution

Liferay model listener ordering

Following is my requirement :
Whenever site is created, with help of GroupListener we are adding some custom attributes to created site.
So assume that you are crating "Liferay Test" site then it will have some fix custom attribute "XYZ" with value set in GroupListeners onAfterCreate method.
I can see this value in custom fields under site settings.
Now based on this values, we are creating groups in another system(out of liferay, using webservices).
So far so good.
Whenever we are deleting the site we need to remove the equivalent groups from other system via web service.
But while deleting site, in GroupListener we are not able to retrieve the custom attributes.
On further debug by adding expando listener, I observed that Expando listeners are getting called first and then delete method of GroupLocalService/GroupListener.
And hence we are not able to delete the groups present in another system.
So I was wondering if we can have ordering defined for listeneres.
Note: Since we were not getting custom attributes in listeners we implemented GroupLocalServiceImpl and with this we are getting custom attributes in delete method on local environment but not on our stage environment which has clustering.
You shouldn't use the ModelListeners for this kind of change, rather create ServiceWrappers, e.g. wrap the interesting methods in GroupLocalService (for creation as well as deletion).
This will also enable you to react to failures to create records in your external system etc.

what alternatives are there to using global.asax?

I am using my own custom authentication with IIS, and I want the server on every page load (no matter what type of file) to first check the Application variable to see if the user is authenticated and authorized to see the site. In global.asax this could be:
void Application_Start(Object Sender, EventArgs e)
{
if(Application["username"] == null)
{
Response.redirect("login.aspx");
}
}
The problem is that this site has multiple sub-roots. That is, http://example.com/site1 is a completely different website from http://example.com/site2 . Therefore, I would like said Application_Start function to work on site1 but not affect site2.
If global.asax was customizable at directory level, then this wouldn't be a problem. But since there is only one global.asax per server I cannot implement this solution.
What alternatives are there to global.asax? or can global.asax be different somehow for each directory?
HttpModules are an alternative to global.asax
(see also https://www.codeguru.com/csharp/.net/net_asp/article.php/c19389/HTTP-Handlers-and-HTTP-Modules-in-ASPNET.htm
http://codebetter.com/blogs/karlseguin/archive/2006/06/12/146356.aspx )
HttpModules are registered in web.config; which, conveniently, is customizable at directory level. So every directory can have its own unique set of modules (that are inherited in lower directories). All modules have the same functionality as those found in global.asax .
Basically, every page request gets passed through every registered module before it ever gets to the actual page code itself. This happens regardless of what kind of request it is:
"page.aspx" "page.html"
| |
( | module 1 | )
( | module 2 | )
( | module 3 | )
V V
(handler 1) (handler 2)
((a much better picture and description can be found at https://www.codeguru.com/csharp/.net/net_asp/article.php/c19389/HTTP-Handlers-and-HTTP-Modules-in-ASPNET.htm ))
So then all you need to do is define your code as a module instead of in global.asax . If the user isn't authenticated, then: response.redirect("login.aspx") will stop control from ever reaching the handler and parsing/returning/running the requested page.
It's a little more complicated than that, so a better description/tutorial can be found at the codeguru website.
I'm pretty sure that your code is going to allow access to everybody once a single person logs in - probably not what you want.
According to http://msdn.microsoft.com/en-us/library/ms178473.aspx:
"Called when the first resource (such as a page) in an ASP.NET application is requested. The Application_Start method is called only one time during the life cycle of an application"
Furthermore according to http://support.microsoft.com/kb/307598#1
"Application state variables are, in effect, global variables for each ASP.NET application."
I would suggest you use the built in Membership API and restrict access using the web.config files.
If you are open to using the Membership API rather than rolling your own authentication mechanism, you can use the web.config to check if a user is authorized for a particular folder. You can also relatively simply have the user log in on one site and automatically be logged into the other sites by sharing authentication tickets -- provided they are all on the same root domain.
For sharing authentication tickets see:
http://msdn.microsoft.com/en-us/library/ms998288.aspx and http://www.netomatix.com/development/singlesignon.aspx
For how to use the web.config to restrict access:
http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=85
Actually I believe there's just one global.asax per asp.net application. If you want example.com/subsite1 to be a different application from example.com/subsite2 you can create two different applications in IIS. As a result they'll run in entirely different application domains (although they may be in the same process (aspnet_wp.exe or w3wp.exe) and even share application pools). As such, if they're different applications they should also get to have independent global.asax files.
To turn a directory into an application. Open IIS->Find the directory/sub site, right click->Properties->Home Directory tab->Click "Create".
For more information on application domains and worker processes, consider reading this blog entry. Hope that helps.

Resources