How do I access the cookies and make them into scope variables? I can get the cookies but I am at a loss for how/when/where to create scope variables for each one once I have them
The key is how early you can get the cookies. I don't know if the map is filled at beforePageLoad or afterPageLoad. From there you can iterate the map (use keySet()) and create / update in sessionScope or viewScope. You just need to bear in mind sessionScope may be shared across browser tabs.
For that matter you could just move the entire cookie map to a scoped variable. Not quite as usable when you need to access them. I assume you just need to find one or two cookies? You just need to get those values and move them where you want like Paul said.
Related
I built a prototype db using an appLayout that is working well with title bar tabs to 3 separate dbs. The prototype contains a setup document with server and filename for the 3 dbs. A SSJS library used by each xpage checks for a sessionScope variable. If null, it gets the locations of the 3 apps and sets 2 sessionScope variables used by all 3 data sources. Now I need to add complexity so the 3 tabs will open the correct instance based on the user's geography. I need some help and assume others have done something similar.
My design thoughts are to...
Add a panel and a djFilteringSelect or ComboBox in the appLayout searchbar
Use CSJS and localStorage to get and set the geography
Store the geography in sessionScope.geography
Continue to use sessionScope variables for data source instance locations
Don't get geography from localStorage when opening every xpage, but get it only when sessionScope.geograhy is not set
Add a home/welcome page and display (redirect to) it instead of the initial db view xpage when sessionScope.geography is not set
I've been playing with this for several days unsuccessfully. I think I'm having issues with timing of events and passing values between CSJS and SSJS.
I would use a session bean. Works like a session scope variable, but you have code that can execute when you do the getDataDBLocation() call (which in EL would be just dataDBLocation). You can entertain a number of strategies if that value isn't persisted:
a name lookup into the NAB. Eventually a field there gives enough info on the location
a geodb lookup
a ping to all servers and use the fastest
if you also implement setDataDBLocation(String location) you can save a user preference back. The interesting point: the location you save doesn't need to be the value returned. So you do a setDBLocation('Frankfurt') but the get would return "server02!!europetasks.nsf"
Let us know how it works for you
This seems like it should be easy to do but I cannot get it done.
I have an Xpage called Location. There are two general types, A and B. I have a series of views for A and B. They are the same except for the value of that one field.
In the views I want my "New Location" button to automatically populate the type to A or B, depending on whether the user is in one of the A views or B views.
Seems like I would set a scoped variable and then check for that on document creation, but it doesn't seem to work. What is the best practice to do this?
Jesse Gallagher's frostillicus framework on OpenNTF (XPages Scaffolding - http://openntf.org/main.nsf/project.xsp?r=project/XPages%20Scaffolding&SessionID=DN6QBBFGEB) includes flashScopes, which give the facility to pass information from one page to another and get cleared when the page is loaded.
You can use sessionScope variable to transfer data from one XPage to another.
A better approach might be to use URL parameter for your case.
Add for example &type=A to your URL like
http://server/database.nsf/Location.xsp?action=newDocument&type=A
Then you can read this parameter in your destination XPage with param.type like
var type = param.type;
The disadvantage of sessionScope is that it's the same for all browser tabs. So, you need to delete it right after usage in this case. Using an URL parameter instead you don't have to think about that.
for hidden field tampering protection: Id, RowVersion, I use a version of Adam Tuliper AntiModelInjection.
I'm currently investigating a way to prevent tampering of valid options found in select lists/drop downs. Consider a multitenant shared database solution where fk isn't safe enough and options are dynamic filtered in cascading dropdowns.
In the old days of ASP.NET webforms, there was viewstate that added tampering prevention for free. How is select list tampering prevention accomplished in ajax era? Is there a general solution by comparing hashes rather than re-fetching option values from database and comparing manually?
Is ViewState relevant in ASP.NET MVC?
If you can, the single solution here is to filter by the current user ids permission to that data, and then those permissions are validated once again on the save.
If this isn't possible (and there are multiple ways server side to accomplish this via things like a CustomerId fk in your records, to adding to a temporary security cache on the server side, etc) , then a client side value can provide an additional option.
If a client side option is provided like was done with Web Forms, then consider encrypting based on their
a.) User id plus another key
b.) SessionId (session must be established ahead of time though or session ids can change per request until session is established by a value stored in the session object.
c.) Some other distinct value
HTTPS is extremely important here so these values aren't sniffed. In addition ideally you want to make them unique per page. That could be the second key in A above. Why? We don't want an attacker to figure out a way to create new records elsewhere in your web app and be able to figure out what the hashes or encrypted values are for 1,2,3,4,5,6,etc and create essentially a rainbow table of values to fake.
Leblanc, in my experience, client side validation has been used mostly for user convenience. Not having to POST, to only then find out that something is wrong.
Final validation needs to occurs in the server side, away from the ability to manipulate HTML. Common users will not go on to temper with select lists and drop downs. This is done by people trying to break your page or get illegal access to data. I guess my point is final security needs to exist in the server, instead of the client side.
I think a global solution could be created given a few assumptions. Before i build anything I'll like to propose an open solution to see if anyone can find flaws or potential problems.
Given all dropdowns retrieve their data remotely. - in an ajax era and with cascading boxes this is now more common. (We are using kendo dropdowns.)
public SelectList GetLocations(int dependantarg);
The SelectList will be returned back as json - but not before having newtonsoft serialization converter automatically inject: (done at global level)
EncryptedAndSigned property to the json. This property will contain a Serialized version of the full SelectList containing all valid values that is also encrypted.
EncryptedName property to the json. This property will have the controller actionname - For this example the EncryptedName value would be "GetLocations"
When the http post is made EncryptedName : EncryptedAndSigned must be sent in the post also. For this JSON POST example it would be:
{
Location_Id: 4,
GetLocations: 'EncryptedAndSigned value'
}
On the server side:
[ValidateOptionInjection("GetLocations","Location_Id")
public ActionResult Update(Case case)
{
//access case.Location_Id safety knowing that this was a valid option available to the user.
}
To hand over values from an XPage to a custom control, which approach should be used ?
a) Define properties in the custom control at design time. Fill in the properties at the XPage with computed values. Use the value via 'compositeData' in the custom control at runtime.
or
b) Put the value in a session scope variable at the XPage in BeforePageLoad event. Bind the session scope variable to the field in the custom control.
The session scope is primarily intended for ensuring that values persist as the user navigates between pages. I like to call it the "shopping cart" scope: if you built an e-commerce site in Domino, you wouldn't want the site to forget that a user had added a product to their cart just because they clicked back to the home page. So this scope is also useful for features like remembering search / sort / filter options as the user navigates the app so each time they navigate somewhere else and come back, it remembers their prior behavior without having to store this information permanently in the NSF.
For passing in-page information to a Custom Control from a container, however, compositeData is definitely the way to go. This is because that variable is populated with the passed parameters only for the duration of the processing of the relevant control. Once that control has been dealt with, all pointers to the passed parameters are cleaned up automatically, which provides incremental scalability improvement for each instance compared to storing the same information for the duration of each user's session.
There will be cases where there is overlap: a given Custom Control might reference information that is appropriate to store in the session scope. In this scenario I like to mix the two techniques... for example:
<xp:inputText value="#{sessionScope[compositeData.scopeKey]}" />
The above syntax allows a Custom Control to be passed by its container the identifier for where in the session scope the relevant information is stored. This provides some serious flexibility, because I can drop the same control into multiple contexts, with each telling the control which information it should retrieve / store in scope.
Lets say user A logs in and a sessionScope variable is set (This is just an example):
sessionScope.put("ABC", "ABC");
Now user B logs in and his sessionScope variable is set:
sessionScope.put("XYZ", "XYZ");
Is there a way where I can get all these sessionnScope variables/objects belonging to different users?
In theory, you could register a sessionListener that stores in the applicationScope a pointer to each sessionScope that is created... but, in my opinion, that's a very bad idea. You'd have to be extremely careful to avoid exposing users' session data to each other.
use the debugBar
http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&name=XPage%20Debug%20Toolbar
Session scopes belong to a single user so you cant retrieve them out of the box. You could add logging to the xpage/business log so you can keep track of the things that are going on. Another approach is to login as the user where you want to now the scopes from and use the debugbar to investigate
SessionScope variables belong to a single instance of a browser/client. If you are Anonymous and log in as "user one" you have the same sessionScope as you did before. The same is true if you logout and log back in as "use two".
I have built an app which runs a method in the before page load of every page to assure the necessary sessionScope data is setup. One part of that data is the name of the user for whom the data is defined. That way, if the user name changes the we clear the data and reload it for the current user.
Using this approach you could define a MAP or JSON object with the username as the key which would keep the differences as people log in and out, but I am not sure that is a very sensible thing to do since changing identities is only realistic in development and testing. It is not a normal thing in production.
/Newbs