I am building a complex web page, that has many users/groups/permissions where user can see all/some/none of the object of specific type according to the ACL (using Symfony2 and Symfony2 ACL).
What am I dealing with now is that I don't want to show every UI element in the frontend and just throw 403 error if user does something that he has not permission for. Hidding elements that the user has no permission to see would be better for UX.
It is like if I show a product info page for the user, I don't want to show the EDIT/DELETE buttons, if user does not have permission for doing that on this product or all products (class scope permission).
With Twig and server side rendered templates it would be easy as adding bunch of permission checks in template
{% if is_granted('EDIT', product) %}
<button>Edit product</buttom>
{% endif %}
But how to handle this in clientside with AngularJs?
What I was thinking is the following:
Create a controller method that serves Twig templates rendered server side for AngularJs. This takes a parameter of id identifying the object, which the user must have permissions on in order to see the EDIT/DELETE buttons rendered in the template (Twig and is_granted() handles this serverside)
User ask to view a specific product /product/1. The router templateUrl would be /templates/product/view.html?object_id=1, where object_id identify the object, that should be used while rendering templates serverside to grant or deny rendering ui elements.
The product JSON is then fetched and put in the template, which has already been rendered serverside, and has some Angular {{ }} waiting for product data to be placed in.
Are there any similar cases solved using other serverside technologies that you are familiar with and can be taken as an example to lead me on my way to success?
In our project client side Angular code is enough.
Back end wont ever send any data to front end user have no permission to view/access. (403)
Front end present login page to user with witch user can authenticate. Front end then send provided credentials to Back end, which is responsible for actual checks.
Back end will provide Front end with user role/access right/privileges. If those are more complex dedicated API endpoints will be provided. (Fe: Can user access this? Be: No. Fe: that? Be: Yes, but not delete. etc.)
Front end will use if's on data returned from Back end to conditionally render UI parts.
Do note that I use back end and front end, as described technique is framework agnostic and will work with pretty much any.
For Angular we created CurrentUser service that had is('role_name') that would return true if user had assigned role, false otherwise. ng-if or plain old if(), then where used to conditionally render html tags/data.
Related
I've angular app with lots of states and modules etc. Now, I want to send a link to the user. When user'll hit this url, I want to redirect him to a new tab rendering only that particular state (specified in URL) i-e I don't want anything else to be visible to the user. Or you can say, I want to open a popup window rendering that particular state's html in popup window . This is the approach that comes to my mind to sort it out.
Ps. There are Rest APIs at the backend which I am calling through angular resource service to bind data with the model of the views
Option
I've rest APIs on backend, So, I was thinking to developing s separate Nodejs application, And I will send nodejs application url to the user and in the default/home route I'll call backend API and, the returned resultset will be rendered in html file within nodeJs application and this way, I'll render the corresponding data to user's browser window.
This is the flow for that
I don't know if that is right or clever approach. Please suggest me what will be the best approach to sort it out.
Thanks in advance.
This is what my app looks like
Everything in the left side-nav is a module and clicking on this I am routing to a different state. I am using angular-material and lots of other dependencies in this project.
And this is what I want.
I'll refer a link to the user for example www.myapp.com/specificpage.html. And hitting this url, a new tab/popup will be opened rendering state defined in the same app but with some non-editable url. And it should like.
There are multiple ways to achieve this and each approach has advantage and disadvantage. You have to choose depending on requirement and architecture. Details are below-
Create a separate app - You can do it through separate code base or use the module based build process and include this module only for new app.
Divide application is two part, public pages and private pages - Include this page and required APIs for this page in the public modules for your app.
Send token in the link - If you want to make secure page, send short lived token in the eMail and validate token on the server before displaying page to the user.
I am using Grails 3.1.4 together with AngularJS.
Certain sections on the page are for logged in users only and I want to restrict access to the according html templates, so only they can access them.
I have set up the Spring Security so that access to those templates is restricted.
The problem I encounter is, that it appears that all the html templates are loaded when the page is loaded the first time. At that moment the user is not logged in, thus the server returns a 401 error.
Once the users is logged in and tries to navigate to the restricted page, angular checks the template cache, realizes nothing is there and returns a 404 error.
When I look at the index.html in the developer tools, I can see, that the asset pipeline includes a script tag for each template, so all the templates are loaded at the initial page load.
Is it somehow possible, to have the templates loaded and cached dynamically when they are needed for the first time?
You might allow HTML templates to be accessible to all. For restricting the content, you might need to implement Spring Security token based Authentication and check accordingly what content should be visible to whom.
Reference : http://alvarosanchez.github.io/grails-spring-security-rest/2.0.0.M2/docs/index.html
I'm building a UI using AngularJS that consumes a REST service:
Here is the Server API
/items/ GET
/items/:id GET
/items/ POST (to create new item)
/items/:id PUT (to edit item)
/items/:id DELETE
What are the best practices when setting up the routes in Angular? These routes would map to the server REST API, but obviously there is a problem. I'm guessing I would need the action as part of the URL, right? Something like this:
Angular Routes:
/items/
/items/:id
/items/new
/items/:id/edit
/items/:id/delete
However the above pattern also has a problem. /items/new will match both /items/:id and /items/new so what is the best practice when setting up a route for create?
Also keep in mind that the client side, Angular, routes you're defining could be dependent on your UI. The routes you've defined are more like a traditional web application where you click an "Add New" button that takes you to a new page that has a form that you fill out. However, this may not be the pattern you use for a Single Page App (SPA) as is often created with Angular.
By this I mean that most of the SPA apps I've done don't actually have a standalone "/items/new" route on the client side. Instead, the "/items/new" functionality is handled on the "/items/" route/partial ("page" in traditional web app terms). This page lists the existing items, and there is a form on this page that you can fill out to create a new item. Or, there is an "Add New" button on this page (just like a traditional web app); but, clicking it either slides in a modal form or ng-shows a form that is already defined (but initially hidden) on the /items/ partial template.
Upon submission, the controller hits against "POST /items/" on the server to create the new item, updates scope with the return value from the POST (assuming success, this would be the new item info), and clears/re-hides the "new" form.
Bottom line -- keep in mind that in a SPA you may not actually need a "/items/new" if the UI is such that the new is handled as a capability of the item list page. Of course, if you're needing it to be a standalone page as an addressable endpoint (i.e. you're planning to link to this from multiple places, not just from within the app), then you'll obviously need a direct route.
In our case, we typically don't need a named route for it in our apps and we just have it serviced as a capability of the "/items/" route.
Using UI-Router we can setup client side routing.
Make sure you disable html5 routes, because some browsers still doesn't support html5 and they hit the server api instead of hitting the client route
You can do this by setting $locationProvider.html5Mode(false); in app.config method while defining angular app
/items/ - this is for listing items
/items/{id:[0-9]{1,4}} - this is for displaying one item in detail
/items/add - for displaying new item form
/items/:id/edit - for displaying existing item in Form for editing
/items/:id/delete - **This is not required, I mean you just hit the API when
use clicks delete, we cant show any deletion form**
You can use regex for params '/items/{id:[0-9]{1,4}}' this means allow only numbers 0 to 9 and 1 to 4 characters long
I am very new to Salesforce Apex. I created a simple Apex-Class to get all contacts in the salesforce website.
I used javascript code to invoke that class as follows
function runApex() {
sforce.interaction.runApex('AccountRetrieval', 'getAccount', 'name=Rajeev', callback);
}
It's working fine in my laptop. But how can my customers get to access that class to get all their contacts ?
If you can't simply give them access to the contacts tab in the UI to achieve what you're after then you can create a visualforce page with a custom controller. In the controller, use SOQL to run a query for all Contacts and save the result to a list or map. You can then use this variable to pass the Contact data to the visualforce page. If you just want to dump the data to the page as HTML then you can use a list variable to hold the query result and an apex:repeat tag to generate the HTML on the visualforce page. If you want more control over how the data is displayed then you could also use the apex variable to pass the data to a javascript variable which you could then build your HTML from client-side in whatever way you like.
More detail would be needed to give you full steps on how to set this all up exactly how you want but basically you should use a visualforce page to give them an interface to run your apex code from. Access to that page can be controlled via profiles or permission sets.
If this page needs to be visible to people who do not have a user account to log into your org then you can use the Salesforce feature called Sites to expose content to them without the need for a login.
Is there a blog, project, gists or seed out there using angularjs and requirejs that provides authentication not based on routes? I'm working on building a site that will show the user the same rendered view, but different data fed from the server based upon their authentication. I have session handling already written into it, but I need angular to check the server for the session on the initial render for changing login buttons to logout and getting only the data the user wants to see that they've selected.
I attempted to use the angular run method to initially grab the session from the server, but when using requirejs, my app module doesn't exist at the time of calling the run method.
From my understanding, please correct me if I'm wrong, I should be creating an injector or using the $rootScope to carry the user information to routed controller and show the user what they is related to them. If so, then I need to have a service that is initially fired during the project instantiation to retrieve the user's session data. I'd prefer to not use the servers template rendering to put the users session data into javascript if possible.