I am building a website that will host multiple apps. Some apps can only be accessed by certain groups from a LDAP backend. To achieve this on a pure Django stack, I used
user_has_perm
#user_passes_test()
so that certain views can only be accessed by users who has permission to add items (I give the permission to add items to certain groups, they are automatically placed into a group from the LDAP)
However, I am now migrating to a React + Django stack. How can I achieve a similar effect, where you can only access some apps if you are in the correct LDAP group.
Note - I have a single react app frontend that that uses routers to get to different component(apps)
if you have hybrid architecture
the easiest solution is to do the same thing but with view for your react app
user_has_perm
#user_passes_test()
*view_that_renders_template_with_react*
if you have many pages and different pages with react router you can add an additional check if user is permitted to get to this page, you can add this information to the user or make request, if no do something, redirect or throw an Error like Error 403, also you can use native django-rest-framework permissions and check it during the requests, and do something if user has no permission. If you are not using react router, but you also have hybrid architecture (you connect react via django templates/static) , you can make many identical views, check for different things then define urls for them in django urls,
I'm not able to provide more clear explanation and attach code, because there is so much ways to build such app and each requires individual solution, so I just explained possible solutions, which to use and how, depends on your implementation and architechture you've chosen
Related
Is it worth it to use DRF+Ajax+bootstrap to build a website where no app is needed, or is it better to stick to the normal django template language without even Ajax? I want to avoid using angular since I don't want things to get complicated.
I want to create a website where a user or an admin logs in and accesses a different set of views and performs different actions.
Sorry for my primitive question, I'm a newbie in web development and Django.
Django REST Framework is only necessary if you're building a RESTful API; An HTTP service that reads and writes data, usually as JSON payloads.
Services are typically created to allow external clients such as mobile apps, single page applications (React, Angular, etc.) or 3rd parties to gain access to your data.
It is not necessary to create a service if you just want a traditional "form-based" web application. What you're describing in your question is totally possible with the standard Django implementation. User logins, user access levels, database access via the ORM and templating are all built in. All without any need for a REST service.
You can always add Django REST Framework later when you know you'll need RESTful services since DRF uses the same models that the normal views do, it just wraps them in serializers.
You can accomplish what you're suggesting easily without any special additions or changes to Django. Just because a certain way of development is popular does not mean it works in every situation.
What kind of libraries are you using for user role management in your React applications? Any kind of directions are welcome. By role managing I am mostly reffering to showing or hiding certain components of the application.
At the simplest level, I would think you would just reflect the user role in your state, and have components render (or not) accordingly.
If you want to completely hide the existence of privileged code from a non-privileged user, you may need to factor common code into a shared library between user and admin apps, or generate two separate bundles, and authenticate access to the bundles.
Either way, the important thing is that you securely authenticate requests that would change server state in privileged ways.
Is it possible to create a single Meteor application having multiple domains and displaying different views/layouts depending on that domain?
For example, i have a admin interface accessible on admin.myapp.com and the two domains storeX.com and storeY.com. Both domains should point to the data from admin.myapp.com but displaying the data (mostly) independently of each other.
This may not be totally updated to 2014 standards, but I did answer this question before:
How can Meteor handle multiple Virtual Hosts?
And with the same setup, you can use Passenger (for nginx OR apache2) for Meteor. Here's a complete tutorial for using Passenger with Meteor, but keep in mind you have to integrate the multiple virtualhosts/domains to this tutorial yourself.
Perhaps a better approach would be to use Meteor's Pub/Sub capabilities, rather than sharing a DB per say. It's entirely possible to publish and subscribe across meteor apps, or indeed any implementation using DDP.
http://docs.meteor.com/#/full/ddp_connect
You can use the partitioner to send different views of the data to different users based on the domain name they hit.
See How can I share MongoDB collections between Meteor apps? . Basically the idea is that you build two meteor apps which would share the mongodb and collection(s) data.
I’m working on a SPA built with DurandalJS, which is hosted on app.example.com. The API is hosted on api.example.com. We're now planning to add backend administration for ourselves, to overlook our clients. We'll each have an account and we'll be able to manage our client stuff.
What we're trying to figure out is where to host the backend.
If we keep it on the app subdomain, we'll only have to add a new role (admin) to the existing application, but this will allow regular users to log in ti the backend if our credentials are somehow leaked.
If we clone the existing application to admin.example.com, we'll always have to worry about the code being in sync, but it will be safer, because the admin subdomain will be closed to the public and the login for admins will require a different set of api and private keys.
How should we handle this? If we go with #2, are there better ways to share code between two apps without the extra headaches?
I personally like the second approach to go with different subdomains.
Duplicating the codebase is not really necessary since you can leverage the cool features RequireJS provides to map aliases to your modules. The importance here is that through extracting the business logic into modules you can serve different implementations.
I've created a small GitHub Repo called durandal-multisite to explain in detail how you would proceed.
The general idea is to:
Keep the same viewmodels/views
Extract businesslogic (should be anyway done to follow proper SoC)
Create 2 main.js implementations (frontend/backend)
The respective main.js setup a RequireJS map to the aliases requested by your viewmodels
which then deliver the concrete module implementation
I think you need to distinguish between creating subdomains that point to the same application or creating two separate applications.
I think in order to give a full answer, we need to identify some important aspects of your app first:
How is your authentication and authentication implemented? Is it part of the SPA? Is it before loading the SPA?
Will the code of the application be 100% the same as the admin application? What do you mean by keep in sync?
Making some assumptions I could give you some answer, it might not be accurate but could help you:
Subdomains are cool, you get some information upfront (which subdomain the user is trying to access) so you can qualify requests easily and determine some stuff before actually hitting the application server. However, I don't think your problem here is in which subdomain the application should live.
The first thing you need to answer is how you would qualify a user from being an Admin and a regular User. Obviously you should not rely on a subdomain to do so. Probably this logic would live in the login process based on some data (probably from a DB).
The next thing that you need to know is how your application changes depending on the role:
If your application will be 100% the same (same code) and will react dynamically based on the role that is logged, you don't really need anything special. All you need is make sure that your application is secure enough to not allow regular users to do admin stuff.
You could use the subdomain and some extra logic so only Admins can use the subdomain. However this is only some "sugar" security to make some separation. The app needs still needs to manage roles and permissions consistently.
-
If your application is not using the same codebase, you need to determine during the logging process in the web application which role is logging in and which SPA application it should send to the browser. To do so, you need a separate logging page or have a modular SPA that can load modules at dynamically.
Probably you would like to reuse some code between applications (admin & user facing apps). You will have some challenges reusing parts of the codebase.
You don't need to worry that much about permissions and roles in the user app but you need a secure logging process.
(Just a reminder) In any event, SPA's should contain logic to manage roles and permissions for the sake of consistency and to avoid user confusion. The main security management is in your API. The goal in any SPA that has authentication and authorization is to have a secure API behind.
Here's my current app structure:
/_css/
/_img/
/_js/
/app/
/lib/
index.html
After reading both answers, I ended up separating the apps while keeping them under the same roof.
/_css/
/_img/
/_js/
/app/
/backend/
/lib/
index-app.html
index-backend.html
This allows an easier way to manage and switch between the apps. I don't have to worry about keeping the css, the images and the libraries in sync or creating a new git repo for the backend.
I've also updated my Gruntfile.js to include a separate building process for the app and the backend. So locally the apps will be under the same /_js folder, but on the server, they'll be on separate domains.
I should have been more specific with my question and include the fact that my problem was more with how I can manage both apps locally, rather than on the server.
Thanks for the answers!
I have a small Backbone application that is currently running on a page within a Drupal site. Currently the Backbone application is served on a page with no authentication - any user can see it.
I would like to use almost the same Backbone application on another page that the user only sees if they are authenticated. However I would like to add some advanced features for these authenticated users.
The difficulty is that I'd like to use the same Backbone code for the two types of users, rather than having two separate Backbone apps. How would you recommend I do this?
I'm naively thinking of this sort of thing:
SearchView = Backbone.View.extend({
render: function() {
if (isAdvanced) {
//render advanced search options in template
}
},
runSearch: function() {
if (isAdvanced) {
// handle advanced options for client-side search
}
});
The problem is that the JavaScript code will obviously be visible to non-authenticated users, and I'm guessing that they can set isAdvanced in their console, and unlock the advanced features that way?
(The authentication process itself is handled by Drupal. If the user is not authenticated to see page B, they are automatically forwarded to a login page. That isn't the problem - how to organise the JavaScript code is the problem.)
Do I need to maintain two separate versions of my Backbone app? Or is there a way I can share code between the two?
For context, this isn't a super-secure application, but the advanced features are paid, so I'd prefer it wasn't trivially hackable.
What I would do in this case to minimize developments is just to uglify/minimize your app javascript that'd be the cheapest solution, only a very motivated person would spend time to go through obfuscated code.
I would suggest, have common features defined in a Backbone app, and for advanced features extend common app and add more features on top of it. while rendering depending on authentication level render either common/advanced app. With this whatever you add to common app would be available for both users, and whatever added to advanced app will be available only for advanced users.