GWT RequestFactory: check if members have been set without permission - gwt

I am working with GWT / RequestFactory and a set of customer requirements regarding permissions. Let me explain a basic example:
Every user is assigned to a company. Every user should be able to edit company's core data - but only e.g contact information, website etc. Security-relevant ones like BIC/SWIFT, IBAN, Company name and so on can only be changed if the user has a certain permission XY.
So far so good, on the client side I can check the permissions and disable those fields the user is not allowed to edit. But what would be the most elegant way to ensure on the server side that those fields have not been set without permission?
My problem is that I cannot track changes on the server side. Having #PreAuthorize on every setter is not an option too, because it would end in an authorization-massacre in each and every entity.
At the moment I am following a workaround: every field that is secured / depends on a given permission is passed as an argument to the entity-method and is excluded from the proxy. That way, values cannot be set using the proxy and I can check in my server code if the user has permissions. If not, nothing happens. If user has permissions, I set the values manually. But that produces a lot of boilerplate-code and ugly method signatures because the number of values passed to the method could get large.
I hope you understand my issue. I'm looking forward for your opinions and tips. Thank you in advance.

Well, you can receive many answers (different each other), and all of them could be right, so, at the end is your call. Wait for others answers. I am going to give you the approach that I followed (and it worked pretty well). :D.
Under my opinion, the server should do less as possible, so keep the logic for allowing modify each param on the server I think it is not a scalable solution (if your system has 1M users modifying everything at the same time, will your server work fluent?). I prefer let the client do the job (like Roomba :D).
For solving that problem, in our system we implemented an Access Control List solution. You can store in your db, on each user entity, a list with granted permissions. So, when that information arrives to the client (after user's log in, for example), you can get them, and show the fields that he/she is allow to modify.
Something like:
if (canModifyPersonalDetails(user.getAcls(), ...) ) {
//show labels ...
}
if (canModifyBankDetails(user.getAcls(), ...) ) {
//show labels
}
You can not avoid server call for log in, so it is not a big deal send the extra information (think about the ACLs could be simple list of integers 0 means personal details, 1 bank details....).
If you are dealing with very compromised information and you prefer do some stuff on the server, in that case probably I'd set up a security level, when you are persisting/updating your proxy, I'd do something like:
if (isAllowForPersonalDetails(user.getSecurityCode()) {
//update the modified personal details
}
if (isAllowForBankDetails(user.getSecurityCode()) {
//update the modified bank details
}
user.update();
I am a big fan of clear User GUI's, and a very big fan of let the server free as much as possible, so I prefer the first option. But if you have constraints for modifying user entity in db, or you prefer do not modify your views, or any constraint with security, maybe the second option is the best one for you.
Hope that helps!

Related

TYPO3 fe_user: Log in as two different users at the same time possible?

One of our clients wants to FE log in as two different users at the same time, using one browser. I think this is only possible when using two different browser. IS there any workaround?
Background is this: We wrote a FE extension where user can login and update some of their data. One client is a kind of superuser/admin. He wants to compare and edit data of several users at once.
Authentication in TYPO3 is performed by cookie fe_typo_user and therefore it is not possible to have two users logged in at same time from same browser.
You may advise to use different browsers or virtual machines for your client.
As Viktor wrote - it's not possible. Here I should finish the answer.
Anyway... while you are creating your own plugin you can easily add 'simulate mode' using for an example custom cookies... Block schema is:
[IF isAdmin AND simulateMode == false] {
Display admin's version
} [ELSE] {
Display common user's version
}
You can go even farther and switch the admin to simulate some chosen 'common' user, anyway make sure that will not violate some privacy police.

Yet more questions on RESTful URIs

Numerical IDs vs names
As an example, which of these would you choose for identifying a single transaction, from a single bank account, for a single company:
/companies/freds-painting-ltd/accounts/savings/transactions/4831
/companies/freds-painting-ltd/accounts/1/transactions/4831
/companies/62362/accounts/1/transactions/4831
You idiot, something totally different! Crikey, did you even READ Fielding's dissertation?
Now, I think the 1st one is the most readable. If I have more than one company, or if I'm someone like an accountant managing multiple companies, it's immediately clear which company, and which account, I'm looking at. It's also more bookmarkable/emailable and would prevent 'fishing' for other companies by changing the company ID. I would want transaction IDs to be unique to an account (I.e. Both 'savings' and 'current' accounts could have transaction '1'
A 'company' will be my 'top-level', or 'first class' resource. Nothing at all would ever be shared between companies. As such, it would be the ideal candidate for a shard (or 'ancestor'/'namespace' in Google App Engine parlance). So I'd only have to worry about the account names being unique within one company. Every company could have an account called 'savings'.
Not sure what the situation in the rest of the world is, though LTDs or PLCs in UK would have a unique name, there could be many 'Dave's Window Cleaning' businesses (what's know as a trading name).
The business owner(s) could potentially opt for the top level /company/company-name URI to be public, and contain some basic details like their website, contact details etc, but everything below that would NEVER be accessible by search engines.
So my thoughts/concerns are:
1) Is it reasonable, when someone signs in to add their business, to say "Sorry, 'Dave's Window Cleaning' business is taken. How about 'Dave's Window Cleaning Portsmouth' (Having taken their location in another field)? My worry with this is that, for a more well known company, you're giving away the fact that they have an account with you. Or that someone could use that form to search for names. Perhaps not a biggie.
2) The size of the company name. Would it be reasonable for a name like 'Dave's Window cleaning, gardening, and loads of other stuff'? Thus creating a URL like 'daves-window-cleaning-gardening-and-loads-of-other-stuff/'
3) How to deal with someone changing their business name - I would approach it by creating a new company with that string ID, copying over everything, then deleting the old resource. The original URI would return 404 rather than redirecting - as you can't guarantee someone else won't want to take the now unused name, or even if more than one person has used the same name in the past.
4) Should the 'real' unique ID be an number in the back end, and for every request to be handled by first doing a query for what company ID this name actually related to.
5) The impact of searching for a transaction in the persistence layer.
6) The possibility of URL rewriting, but then that wouldn't work cleanly in GAE, nor would it solve the issue of ensuring company names are unique.
RESTful webservice vs RESTful website
So, we potentially have this lovely RESTful webservice that the latest snazzy iphone/android app can use (delusions of grandeur). But what about the main website itself? I note, right now, that the URL I see at the top of my page is not 'RESTful': /questions/ask is an action. There is no 'ask' resource on the server. It's more the state of the page, the preparation for POSTing to /questions/ - or if I'm editing, PUTing to /questions/{id}
I also note that Stackoverflow has URIs like /questions/362352/name-of-the-question, and that the latter part can be omitted, and one will be redirected to it.
Should I host a completely separate webapp that consumes my lovely webservice (from the same domain)? Do I even need a separate REST server, or can I rely on content negotiation (JSON/XML) and HTTP verb to select the right method (I'm using Jersey), and return the right representation?
So I could have /companies/aboxo/ return the whole HTML page (using stringtemplate.org) if it's a GET /,text/plain or test/html, and JSON/XML for others?
But what happens for 'add/edit/delete' transaction? Would GET / /companies/freds-painting-ltd/savings/transactions/?template=add be ok (or GET ../transactions/352?template=edit), and that would return the right HTML?
Thinking about this last detail is driving me mad for some reason.
Comments, suggestions, outright ridicule - all welcome!
Marcos
Rails solves the "id vs name" problem by displaying both in the URL but using only the id to actually identify eg:
/companies/62362-freds-painting-ltd/accounts/1-savings/transactions/4831
ie - for the ones that have a "pretty url" the function that generates your path write both the id and the name... but for your router, where relevant: you strip off everything thats not the id.
incidentally, it means your customer could actually write whatever they like into the URL and it'd make no difference:
/companies/62362-i_luv_blue_turtles/accounts/1-your_mum/transactions/4831
and your router still just sees:
/companies/62362/accounts/1/transactions/4831
:)
For a cannonical URI I suggest just /transactions/{id} as I presume the transaction knows what the company and account is. Therefore, #4 :-)
Is SEO a concern? I presume you don't want random folks off the internet googling for X company's transactions?! Therefore, I would just keep names (which may change) out of the URI.

Question regarding fine-grained authorization and MVC2

Background: Completely new to MVC2. Has C# experience, but limited web experience.
I need more fine grained access than simply assigning a Role to a user. The user may have the role at 0+ points in a tree.
/
/Europe
/England
/France
/USA
For example, a user might be moderator of all forums under "Europe" and have access to posting news in France.
The two example controllers have actions as these:
ForumController:
public ActionResult DeletePost(int id) { ... }
NewsController:
[HttpPost]
public ActionResult Post(int treeID, ...) { ... }
How should I approach this? From what I gather Membership+RoleProvider cannot do this level of fine-grained control.
Previously I have written custom user/role/auth system which supported all this, but it was incompatible with "the standard" controls such as LoginView.
The goal would be to have roles allowing access like so:
NewsAdmin
Add news
Edit news
Delete news
NewsPoster
Add news
Therefore, the Post action of News controler should check: Does user have "Add news"-access where he is trying to post?
I would really like to somehow specify this using attributes, so the actual action code could be cleaner and just assume that the caller has appropirate access.
Hope the question makes sense, and I can get some pointers on where to read.
(Oh, and I'm sure this question has been answered in some variant before. I just can't seem to find it. I won't mind single-link replies, if you feel they might be helpful to read)
I think you're being too quick to dismiss the role provider. If a user had a role called NewsAdmin_Europe_AddNews that would pretty much answer the question, wouldn't it?
Once you've made your authentication scheme work with the role provider, you need to tie that into MVC. Subtype AuthorizeAttribute and override AuthorizeCore. Warning: Your code here must be thread-safe and re-entrant. Call base.AuthorizeCore and then test for the specific role based on the URI/query (you won't get route values since this can be served from cache, bypassing MVC altogether).
This is some work, but will be more secure in the end than trying to reinvent membership.

Need help with Zend Framework dynamic Namespaces

I want to make my system redirect unknown requests such as
www.address.com/a_company
to the adress
www.address.com/companies/company/ and display the company a_company if it exists in the database, otherwise throw the user to a 404 not found page.
So in detail, I want to make namespace that is as the first example dynamically, if the company exist in the database, I have no problem connecting to the database and retrieving information or finding a way to parse a company name, I just need help how to make my system check and run a function every time the address doesn't exist and show the second page (/companies/company/)..
I am using an Acl as well, but I think it should be fine if the page is /companies/company and then possibly add /?c=a_company or similar.
Thank you.
/Marcus
simply create a front controller plugin which checks the request params agains the database before the request is dispatched.

What's the best action persistence technique for a Catalyst application?

I'm writing a Catalyst application that's required to have a fairly short session expiration (15 minutes). I'm using the standard Catalyst framework authentication modules, so the user data is stored in the session -- i.e., when your session expires, you get logged out.
Many of the uses of this application will require >15 minutes to complete, so users will frequently submit a form only to find their session state is gone and they're required to log back in.
If this happens I want to preserve the original form submission, and if they log in successfully, continue on and carry out the form submission just as if the session had not expired.
I've got the authentication stuff being handled by an auto() method in the controller -- if you request an action that requires authentication and you're not currently logged in, you get redirected to the login() method, which displays the login form and then processes it once it's submitted. It seems like it should be possible to store the request and any form parameters when the auto method redirects to the login(), and then pull them back out if the login() succeeds -- but I'm not entirely sure of the best way to grab or store this information in a generic/standard/reusable way. (I'm figuring on storing it in the session and then deleting it once it's pulled back out; if that seems like a bad idea, that's something else to address.)
Is there a standard "best practices" or cookbook way to do this?
(One wrinkle: these forms are being submitted via POST.)
I can't help thinking that there's a fundamental flaw in mandating a 15 minute timeout in an app that routinely requires >15 minutes between actions.
Be that as it may, I would look at over-riding the Catalyst::Plugin::Session->delete_session method so that any contents of $c->request->body_parameters are serialised and saved (presumably to the database) for later recovery. You would probably want some rudimentary check of the POST arguments to ensure they're what you're expecting.
Similarly, create_session needs to take responsibility for pulling this data back out of the database and making it available to the original form action.
It does seem like a messy situation, and I'm inclined to repeat my first sentence...
UPDATE:
Whether you use delete_session or auto, the paradoxical issue remains: you can't store this info in the session because the time-out event will destroy the session. You've got to store it somewhere more permanent so it survives the session re-initialization. Catalyst::Plugin::Session itself is using Storable, and you should be able to with something along these lines:
use Storable;
...
sub auto {
...
unless (...) { #ie don't do this if processing the login action
my $formitems = freeze $c->request->body_parameters;
my $freezer = $rs->update_or_create(
{user => $c->user, formitems => $formitems} );
# Don't quote me on the exact syntax, I don't use DBIx::Class
}
...
my $formitems = $c->request->body_parameters
|| thaw $rs->find({$user => $c->user})->formitems
|| {} ;
# use formitems instead of $c->request->body_parameters from here on in
The underlying table probably has (user CHAR(x), formitems TEXT) or similar. Perhaps a timestamp so that nothing too stale gets recovered. You might also want to store the action you were processing, to be sure the retrieved form items belong to the right form. You know the issues for your app better than me.
I would store the form data as some sort of per user data in the model.
Catalyst::Plugin::Session::PerUser is one way of doing that (albeit somewhat hackishly). I would reccomend using the session plugin only for authentication and storing all the state info in the model that stores your user data instead.
And I totally agree with RET's opinion that the 15 minute limit seems really counter productive in this context.
I came across this whilst searching CPAN for something entirely unrelated.
Catalyst::Plugin::Wizard purports to do exactly what you need. The documentation suggests it can redirect to a login page whilst retaining the state of the previous action.
NB: I haven't used it, so can't vouch for its effectiveness.
In the end, we ended up grabbing the pending request (URL+params) in the auto(), serializing and encrypting it, and passing it via a hidden form element on the login page. If we got a login request with the hidden element populated, we decrypted and deserialized it and then redirected appropriately (making sure to pass through the standard "can this user do this thing" code paths).
You could always have some javascript on the client that keeps the session from expiring by making a small request every few minutes.
Or you could have AJAX check for an active session before posting the form and presenting the user with a new login box at that time if needed.