I need to limit access of content on Drupal site based on the Drupal User's Role.
http://site.com/managers/intro
http://site.com/managers/reviews
http://site.com/managers/up-for-raises
The content can be of multiple content types and isn't limited to one specific content-type. These content types will be used elsewhere on the site so I can't lock down the whole content type.
I can get all the nodes/views to live at those addresses by menu settings when they are created, but I don't know how do I limit access via role other than a bunch of preprocess functions in template.php, but that seems to be the wrong way to do it.
I searched for a module and asked on #drupal-support IRC, but no results came up that use drupal roles as the limiting factor.
Although this is an old question, the Path Access module does exactly this now. Here is an excerpt from its project page:
... gives site administrators an additional layer of access control to all pages of a Drupal site.
Benefits: Although a lot of the Drupal modules provide some degree of access control permissions it never covers all possible requirements users have. Path_access provides the means to restrict pages based on their path alias - meaning you can lock out certain user role groups from whole sections of a site using wildcards.
Seems to me that if 'managers' is always going to be in the URL for that section, you could write a little tiny module that uses hook_init to basically say if the current user's role isn't one of these specified roles, and the url contains "/managers/", then drupal_goto() the login page.
You could also use the Rules module to get that done pretty easily, though if that's the only thing you'd be using Rules for, then it's not worth it.
There are also plenty of access-by-node modules (such as nodeaccess of all things), but these would also probably be more effort that it's worth to accomplish such a simple task.
If i got it right, what you are trying to achieve is to have only certain roles being able to access pages located at a given URL.
BY USING A CONTRIB ACCESS MODULE
As already mentioned by mcrittenden, there is a plethora of modules that allows you to tweak content access. Among them, content access can surely do what you want to, as it allows you to set up permission for each node separately.
BY USING FLAG + VIEWS
Another possible way to do this without coding, is with a combination of the flag module the views module. Here's a brief overview of how I would do:
Create three flags, which you can use to mark content (any type of content!) that will have to be viewed at any of the addresses you specified in your question (for example: create a flag "intro" that you will use to mark nodes that have to be displayed at the page "/mangers/intro")
Create 3 views (one for each address you listed in your question) that would pull out of the DB the nodes you need by filtering them on the basis of your flag.
Set the permission of these views according to the role.
BY WRITING A MODULE THAT CHECKS THE URI AND BLOCK UNAUTHORIZED USERS
You surely can do this. The main advantage would be that it would be a very lightweight solution in terms of CPU and memory load, but there are a few gotchas you have to pay attention to. For example the fact that you can always access your content via urls in the format the http://example.com/node/nodenumber), so you have to check a URL for its aliases too. But also the fact that a user might append a bogus ?something to the URL and you have to write the regex to take in account for such case...
(Also the idea of the rules module given by mcrittenden is a good one, but I did not mention it as I thought to it only when I read his answer).
Hope this helps!
You could also investigate Menu Access, which allows you to associate access between a role and a menu, or a role and a menu tree. (Keep in mind that in Drupal, the "menu router" table is mysteriously not just the UI, but also the traffic router which connects every piece of content to a URL.)
Because all items are associated with menu entries, you do not have the problem of the path alias not necessarily being universal. You can also use modules such as Menu Block to mimic book navigation.
This module appears to be closer to an Alpha or Beta release despite it's full & recommended status, so be careful on production sites.
Related
I want to extend an existing PHP tool which provides automatic CRUD forms for a Database. I want to introduce the possibility to add completely custom php pages (sort of feature extensions). I want to keep the solution as easy as possible, I was thinking about implementing the feature in the following way:
the user-developer adds a new page from an admin menu, specifying the
PHP source file name (e.g. myfile)
the system automatically adds a menu item link for this new page
the system, when a "custom php page" link is clicked, just loads the file (something like: requires './custom_files/'.$myfile.'.php')
What security issues can you see in this approach? The first issue to handle is the fact that the user-developer could use variable names which are used by the system itself, and this can of course lead to problems. In order to handle this aspect, I was thinking about forcing the user-developer to use specific variable names: once you have chosen a prefix, e.g. custom_vars, the user can just modify variables starting with that prefix, e.g. $custom_vars_a, $custom_vars_test, $_POST['custom_vars_test2'] and so on. In this way I will be sure to avoid conflict.
Is there any way to avoid the modification of variables whose names don't start with the specified string?
I know the solution is a bit hacky and not very elegant but I need an implementation very quickly.
Your problem is not, the user can modify your vars - your problem is, the user can do nearly everything, if you allow him, to upload own php files and it's impossible to detect some malicious code.
What you can do is using runkit(link) to load your file in an restricted area - means you have to set disallowed functions, restrict php ini, etc.
But why not simply create an generic crud page, which could handle different databases and could be modified by the user?
An alternate solution would be to use PHP Namespaces.
Assign a randomly generated namespace name to the user. The user is restricted to that namespace. That way you're sure to avoid naming conflicts. Please note that namespaces are a relatively new feature. (PHP 5 >= 5.3.0)
I can't begin to elaborate the security issues this presents, since the user can do anything you, the developer, can do. (shell access, configuration, file system access)
If you expect the users to be malicious (user is always malicious) there's no way to restrict them except maybe using runkit as previously suggested.
I am building a PHP application. For my application, user's profiles / pages are setup and displayed intially by visiting domain.com/username or domain.com/accountnumber.
My question is this - how do you do that, while retaining the ability to make informative application pages that have the url of domain.com/pagename? My main example of this is vimeo, which has vimeo.com/about, vimeo.com/developers, etc., while allowing you to set your username to vimeo.com/username. My concern is that I will launch my application and not have the ability to create the link I want to in the future because it is taken as a username.
What would be your advice, or what has been your experience? Is there a common list to reserve that is recommended? I am not sure what to do. Thanks for the help.
There are a number of ways you can achieve what you asking - read up on routes and routing to gain a better understanding.
Many frameworks offer a way in achieving what you are asking - Zend Framework being one.
Alterantivly, if you are building it from scratch you could implement a different structure i.e.
domain.com/u/joebloggs
domain.com/user/joebloggs
domain.com/a/123456
domain.com/account/123456
This effectivly ensures your urls cannot be affected by someone username. You'll need to look into Mod Rewrite if using creating your own routes.
There are many frameworks available already that offer this ability, try Zend Framework.
You'll need to read up on Routes with ZF to implemented what it is you require.
The answer is you don't design your urls like that. I know vimeo does it, but they probably have run in to this headache.
A better solution is to namespace your resources. Look closely at stackoverflow's urls for better examples of good url design.
If you are absolutely stuck with this url design, consider organizing your "content tokens" (the bit of the url that identifies the thing you want) into groups, and giving them an order of priority. E.g.:
if token matches a static page, show static page
else search for and show user page by account name
else search for and show user page by account number
When users sign up, don't allow them to use names that are static pages. (You may want to reserve a set of static page names in advance.)
If you make a new static page later and a user name conflicts, you can forcibly change his user name and send him an "I'm sorry" email. This will hopefully be a rare enough occurrence that you don't need to solve it with code.
One way would be to use curl or similar to request domain.com/requestedname at the registration, returning an error to the user if the URL doesn't return a 404. As for future conflicts, there is simply no way to do that. You either have to make a list at the beginning of all potential future reserved words and disallow those usernames (impractical), cross your fingers and hope a conflict doesn't occur (also impractical), request a username change from the user when a future conflict occurs (unprofessional?) or use a different namespace for usernames and system pages.
I am looking for expert advice on how to best serve multiple sites with one Drupal instance (using Pressflow 6.x). Let's consider the company needing this is called "ABC Group of Companies" and it has 3 sister concerns. So, altogether there will be four sites:
www.abcgroup.com
www.company-a.com
www.company-b.com
www.company-c.com
Here are the things that are most interesting:
The users will be shared among all
the sites
Each site will "mostly" host their own content (say the welcome text on home page, or menu items - different for each site)
Some contents, will be shown in all of the sites (say, a company-wide notice....or an employee directory)
The theme for each site will be different
Now, I am thinking of having DNS entry so each of the domain point to the same Drupal installation and when Drupal gets bootstrapped, I would like to sniff into the $_SERVER array to know which site is being hit. I'd then like to load the theme accordingly, show the contents specific to that site, and also show the contents that are shared with all the sites.
To make this happen, so far I have created a node type called "Site" and have created four contents for each of the sites. Then for each other content type (say, Page) I have put a node reference to the "Site" content type with multiple value so when creating a new content, the administrator can specify in which site that content will be showed. However, after that I am stuck.
I have tried to understand Contexts, Spaces, PURL - but haven't figured them out fully yet and I believe I could use the community power to help me out. What do you think is the best approach to handle this scenario ?
It'd be greatly helpful if anybody can suggest a direction.
Regards,
Emran
The way you are suggesting is certainly a way that you could do it, but have you considered domain access? I have used it in the past and found it to be very useful. there is also quite a large collection of modules which work with it. Different themes, Options as to which nodes should appear on which sites and shared users are all features that it has.
Hope this helps!
http://drupal.org/project/domain
First up, I strongly second hookds suggestion of using Domain Access Module for this (+1). It has extensive support/features for your scenario and already covers most of the hard parts you'd need to solve yourself otherwise.
Second, if you insist on trying to do this yourself, I can assure you that it is possible, as we have done something pretty similar recently (some special requirements ruled out domain access), but it was a lot of work, especially when functionality provided by contributed modules would not fit well into our 'unusual' scenario.
Given the multitude of special cases you'd have to cover, it is hard to point out a general direction (apart from suggesting to use Domain Access Module ;) but one major point would be to check out the custom_url_rewrite_inbound()/custom_url_rewrite_outbound() function combo. These will allow you to do pretty low level URL manipulations for incoming requests, as well as for URLs generated for output, both of which you'll need to do if you you want to serve multiple domains from the same instance.
Did I mention that you should check out Domain Access Module before you try to build this yourself?
It sounds like there will be virtually no content shared between these sites. Will you be wanting a single login across all sites?
Remember, Domain Access uses 1 shared database.
You could also just do a regular multi-site install, and share certain tables.
I give Domain Access two thumbs up, but just make sure you really need what it actually does.
Also, I would look into the Feeds.module. You can pull content from anywhere (especially another drupal site) and it imports it directly and creates nodes and fields automatically from it.
Can somebody please tell me what is the basic difference between the module and component in Joomla?
If possible, please tell with some examples, so that it is easily understood.
Modules are usually small pieces of functionality designed to _present information in your site). They can appear a number of times, on a number of pages in various positions.
On the other hand, a component is typically more complex, with extensive functionality and capabilities. A component can only be displayed in the main area of a page, and can usually only be displayed in a single page.
Read this article for more info:
http://www.dart-creations.com/joomla/joomla-tutorials/the-difference-between-modules-and-components.html
Taken from http://forum.joomla.org/viewtopic.php?t=344599#p1485432 by David Hurley.
When I'm working with clients here is how I typically explain the differences.
A plugin will manipulate output already generated by the system. It typically does not run as a stand-alone piece, but takes data from other sources (i.e. the content) and manipulates it before outputting to the user window. A plugin typically does not display directly to a user, but does its work behind the scenes.
A module is typically considered to be an add-on to the site that extends the functionality of another part of the system. It usually has fewer options that are configurable by the end user and most of the time does not handle any storing of information into the database. A module usually occupies a secondary portion of the web page and is not considered the primary focus of a page.
A component is the most extensive add-on. This typically adds completely new, or different, functionality to your site and extends the overall site possibilities. A component handles data manipulation as well as input and storage into the database. A component on most sites occupies the main area of the website layout and is the primary focus of the page.
These are just generalizations and there are exceptions to every rule, but this should give you a good starting point.
As far as I can see, any reason for distinguishing between components and modules is hidden in the technique of the Joomla framework. The fact that the main editorial content of a page is provided by a component, whereas subsidiary information (side frames, headers and footers, etc.) are provided by modules is not a real difference as far as the user is concerned. Page content is page content - full stop!
I think it is misleading to confuse users by stressing this difference. The way modules associate with menu items is probably technically different to the way the components do. Components are associated with a page on a one to one basis and they are run by triggering a menu item. Also modules do not always need to access the database whereas this is an integral part of a component. I expect these technical differences ultimately explain why Joomla has built the distinction in the the user interface. Perhaps avoiding this distinction would be the basis for Joomla version 4 - but I suspect this would mean starting from scratch with a totally new CMS :(
A component always displays its results in the "mainbody" area of your template.
A module displays its results outside of the "mainbody" ... usually along the side, top, or bottom of the mainbody.
I would like to be able to programmatically change the outputted path to a Drupal node without using the PathAuto module. We currently process a large volume of content (thousands of articles per day) that get added on the back-end. Rather than use PathAuto to generate path aliases, I would like to have Drupal output the default link but append a partial title for better SEO.
An example of this would be:
/node/123
would be changed to
/node/123/This-is-the-article-title (this path currently will work for the existing node)
I understand how to do this on a theme-basis, by modifying the theme/view templates, but I would like to do it so that anytime the link to the node is displayed anywhere, it adds the title plug.
In addition, I would like to limit it to a certain content type (e.g., 'article').
I am using Drupal 5.x and I would prefer not to use PathAuto (I don't want to store hundreds of thousands of path aliases if not necessary)
I am looking for a solution that does not use PathAuto
Drupal has an internal mechanism for mapping from "/node/1234/" to "/blogs/look-at-what-my-cat-just-did". It's part of the core system, and used almost everywhere, on every request, without you even having to ask. It's fast enough you'll almost never notice it happening - there's plenty of other things in drupal that are -far- slower.
If you're concerned about how URLs are being displayed on the front-end - you should be using the url() function (and filters that do the same with node content) to handle look-ups going the other way.
Where Pathauto comes in is that, when you create or edit content, it will generate a number of entries in Drupal's url_alias table (based on whatever pathauto rules you've created). This is a one-time cost. Unless you're generating content at an astronomical rate - there is a negligible cost associated with doing this.
You're already paying the cost of looking up URL aliases by simply using Drupal. Without hacking core, you can't really avoid it. Storing "hundreds of thousands of path aliases" in the database isn't that big of a deal - if you break that down into the actual storage requirements, you're only looking at a handful of megabytes. Since the table's well indexed, look-ups will be virtually instantaneous. This is core functionality & happens regardless of Pathauto even being on your system.
Unless you have some very odd requirements for the types of URLs you want to map your nodes to, anything you do will simply be recreating a subset of Pathauto's existing functionality (and likely introducing a bunch of new bugs).
you can set your custom path alias for each node type without using path auto module:
install rules module if you already didn't.
create a rule with "before saving content of type 'your type'" event
add a php action and then create your custom path and do the following:
$node->path['alias'] = your custom path alias
hit save and it's done
if you do not want to use rules module, you can use hook_node_presave instead in your custom module
Although Pathauto probably is the best choice, you can use the hook_menu function to mount a URL to a method. That method could programmatically find the node you want based on the URL.
You could try using these two functions:
http://api.drupal.org/api/function/custom_url_rewrite_outbound
http://api.drupal.org/api/function/custom_url_rewrite_inbound
But really, Pathauto is the "right" way to do this.