I am developing an application in cakephp, I have to provide a user page for each user in the site like www.example.com/username, username will changes for each user, when a visitor comes to this url he gets details of the user with that particular username, but in cake username tries to get the controller with that name, How can I done this ?
My first response would be to say "don't do that". What happens if you decide to add a promotions page at some point in the future but you've already got a user named "promotions" or you want to add a forum system but you've already got not-very-nice users named "forums" and "boards"?
Better to do something like www.example.com/users/username. (eg. www.example.com/users/ssokolow) That's how all the sane sites do it. In fact, on a related note, Mozilla just redesigned the addon collections system so that collection names are namespaced under the usernames to solve a similar issue.
Anyway, whatever you decide, instructions for customizing your URL mappings independently of your controller designs are in Section 3.4.5: Routes Configuration in the CakePHP 1.3 manual.
You'll want to set up the order of precedence so that CakePHP tries everything else first (like the login page and the submit handlers for forms accepting user data) and then tries your username mappings as the last thing before giving up and returning a 404.
You'll still have to manually maintain a list of usernames that are banned because their profile URLs would be overridden by site-global stuff (eg. login) and you'll still have to watch out for cases which malicious users might be able to exploit to trick other users into something, but it will work.
You can do it with routes as a fallthrough at the end of the routes file, but it's not advisable - ssokolow has explained why. I have used something very similar for a CMS, but for pages rather than users and uniqueness was maintained by the system.
If it's essential that the URL reads like www.example.com/username rather than www.example.com/users/username then I would look at doing it by apache rewriting the url. This will probably still give you problems if a username coincides with a pagename and may well be confusing for visitors not to mention search engines.
Keep it simple - don't give yourself a headache.
It's a nice feature for users to access their accounts in this way and, contrary to other answers, I don't think it's a headache or undesirable in any way.
The best way to achieve this is with routes, but not manually - database driven routes. Mark Story has a great article on the topic and I've used this approach with great ease and success on very large websites:
http://mark-story.com/posts/view/using-custom-route-classes-in-cakephp
The only change I make is that I maintain a table called "routes" and have a corresponding Route model. The routes table simply has id/name/value fields. The name is the nice URL (in your case "somegreatuser"), whilst the value is the system URL (e.g. users/view/123).
All you need to do is maintain a blacklist of reserved usernames which is easily done using validation in the Route model.
Related
First off, I am new to Symfony, so I don't know the exact functionality of bundles like FOSUserBundle etc., as well as the terminology.
I am looking for a way to use the Symfony security component in a way that enables me to decouple a user's login credentials (say, a login name and a password, maybe the roles) from the actual user meta data (like first name, last name, groups, birth date, etc.).
The idea is that a user can login with different sets of login name/password and still be recognized as the same user (in the end that means, getting the same User object).
To me, this comes especially handy in combination with multiple authentication providers. For example, if I wanted to enable my users to login via an OAuth2 service as an alternative to logging in with their locally-hosted login name/password-combination (like StackExchange does, for instance), how would I do that?
I have read multiple pages of documentation of Symfony, e.g.:
https://symfony.com/doc/current/security.html
https://symfony.com/doc/current/security/entity_provider.html#create-your-user-entity
This latter one even says at 1) Create your User Entity, that a password is a field of User.
I have recently created just that, first I named my classes UserCredentials and UserDitails and because of the confusion of the getUser function i decided to rename UserCredentials to User. I agree with Alex Blex about the relation (manyToOne on the User side). When you decouple your login and metadata you will need to learn how to embed forms or creating your own form models, which is something I am currently working on and you might need to implement callback functions for deleting and updating entities. The more I work on my UserBundle, the more it looks like the FOSUserBundle. There is quite a bit of work of designing it to work well but it's great for learning. If you wish to inspect how the FOSUserBundle works, after you install it, you can find it in the vendor/friendsOfSymfony folder, it might provide a few answers.
I come to you because I'm a little bit lost in the implementation of a specific project...
Here is the configuration of my project:
- A Wordpress website
- An external database outcome of the ERP "OpenERP", containing a table that contains hundreds of users.
In the Wordpress site, I need to create a form that will allow visitors to register in the external database. I also need the visitor to be registered as a user in the Wordpress website because in the near future, registered users will have access to particular content via Wordpress.
In addition to this, the client wants to continue to add new users via OpenERP. In this case, the new user will also need to be created "immediately" in Wordpress.
How can I do this?
Thank you in advance,
Cédric
I looked at "OpenERP" real fast, hoping there is an API. Instead I got confused on the product, just a little. There are fundamentally a few ways to go, here is the path I would explore :
Does "OpenERP" have any type of API for adding and polling users? This is the way to go. So when a new user is registered (created) in WP you can hook the creation via wp_insert_user() see : http://codex.wordpress.org/Function_Reference/wp_insert_user to get started. The hook would check with OpenERP for a user ("does exist") and create if new to OpenERP.
When OpenERP has a new user created, ideally you can send the details to WP, in any number of ways, to create a new user. Creation of the user can include forced PW creation, random PW, and even welcome emails. See wp_create_user via http://codex.wordpress.org/Function_Reference/wp_create_user. You could create an API, a hidden method, an adaptor, etc.
The unanswered question is "What features are available in OpenERP to talk to a remote site over http or the network?". Additionally, what security holes are you opening up and how do these concern the business?
Technically, creation of a password and account, in any professional situation, requires secure practices. SSL/https or possibly SOAP/WSDL to the rescue?
The bottom line : Wordpress has all of the tools, hooks, and features needed to accomplish your goals. What does OpenERP have to allow you to meet these goals?
One final concern, you could have a situation of user conflict - a user created in OpenERP and WP. Some extra logic may be needed, as well as a consideration of how you (as the programmer) choose to define what makes a user unique (email can change, making email a junky unique identifier), user names also can change (not in WP). If these attributes change (edited) you could have heartburn. The entire CRUD cycle needs to be accounted for in detail on both systems. A WP ID to OpenERP ID relationship table, with status, will probably become a requirement.
There are a few other ways to go, but above highlights how I would begin thinking about the problem.
Hope this helps.
i've been using symfony 1.4 to build a project that i didn't quite think through all the way. the site has four user types: A, B, C, and users who aren't authenticated. i need for each user type to have their own set of routing and actions. when a user of type A visits mysite.com/ he will see something different than users who are B's, C's, and not logged in. A users might also have these routes available to them: mysite.com/users, mysite.com/groups, etc., whereas B's, C's, and non-authenticated users might not. basically, sometimes users might share some routes (like /), and sometimes they won't.
symfony unfortunately loads the routing before it hits the user filter, and as far as i can tell there's no easy way to repopulate the routing on the fly and redispatch. using switchTo also seems horribad because i'd essentially be loading the application twice for each request.
basically i need the framework to look at the users type and load the appropriate routing. any solutions involving symfony are desperately welcome! D:
Think about your application design. URLs are identifiers to Objects. It's not a good design to use the same URL for different things.
Maybe if the type of Users are really different you can also consider to create different apps for the interfaces. Then you can also create different session cookies.
URLS can then be
/ the frontpage
/groups the group page for all normal users
/admin/groups administration interface for groups
I am developing the ability for administrators to log in and I'm to the point of creating the admin log-in page, but I'm somewhat torn as to where the best place to put it.
For details, this is part of an MVC framework, and the administration portion is in it's own folder - /admin; so administration is completely separate from the public portion of the site.
I would like to place the actual log-in page in its own php file for security by separating it from the rest of the site. That way if they bust one, they don't bust all. However, then you get to the point of processing the log-in request - should it be in the same PHP file as the log-in, or should it reside in another file, or should all of this just be part of the framework?
Any suggestions would be much appreciated.
EDIT: just for some clarification, this is my first time creating any sort of user system, so please bear with me :) (Any good tutorial/example links are greatly appreciated too).The admin portion of the site is in it's own folder but uses the same base files, classes, etc as the front end - the files are only overwritten in the admin portion as needed. Also, an 'admin' is just a certain user type - roles and permissions have already been figured out.
I'm just having a hard time starting - particularly where to implement/put the login form. I thought it would be best for security to have a physically separate file for login, but I see that might not be the case.
I agree with the rest of the posts, Admin should be in the same work-flow. Here is a good example to reference.
Using the same login system for both admin and users will enable you to simplify your application. First off, you'll only need to create one login form. Secondly, if the admin section is part of the same codebase, you'll gain a huge benefit from being able to access all of the classes used throughout the site. If you used an MVC architecture, you'll probably want to use the same models in the admin as you do on the site. Even if you didn't, there is probably still a lot of code you can reuse for the admin section (base classes, database abstraction layer, shared settings/configuration, etc).
IMHO, Admin should login through the same form as regular user, but permissions should allow him to view additional content.
You can place admin forms in any folder, and then allow admin to access it.
I think the admin user should just be another class of user (or be an option for a normal user). Take note that there's slightly more chance of granting access to a normal user by mistake with this approach.
I am currently writing a CMS and remember someone (it might have been on here) criticise the existing CMS for not having a robust enough user permissions system. I've got a method planned out but it I feel it has fallen into the usual trap of being a bit too fine-grained which makes understanding and implementing it a horror for end users.
I think having a range of default user roles with permissions would be the answer to this, so I suppose my question is this:
What are the default roles you would like to see in a CMS and what sort of permissions would be associated with these?
Thanks in advance!
This is the "best practice" I have ended up with in most projects and am very happy with:
1. Roles
When it comes to roles, I recommend great flexibility, i.e. the ability to create and define user accounts and groups freely (roles like "contributor", "manager" etc. are not hard-coded, but put into a configuration file that can be changed per application). The role configuration is unaccessible to the user, but the engine itself should be free from hard-coded roles.
2. Rights
Rights is where things need to be easy to understand and implement.
I have made very good experiences working with, and checking against, very fine-grained rights on the code / API level:
see
view
edit
change name
rename
delete
move
change rights
etc.
but the user never sees those. For them, they are grouped into a very small number of "right groups":
Read Only
Edit
Administer = Move, rename....
The user never sees the "move" right, but only the "Administer" rights group.
That way, you retain the full power of fine-grained rights in your code for the future - you can, for example, easily accommodate for a rule like "interns must be able to edit pages, but not be able to change their titles, nor to delete them", adding a valuable asset to the CMS. For the end user, this functionality remains invisible, and the rights system easy to use.
I asked this question a little bit ago and got the following response.
admin //Manage everything
manager //Manage most aspects of the site
editor //Scheduling and managing content
author //Write important content
contributors //Authors with limited rights
moderator //Moderate user content
member //Special user access
subscriber //Paying Average Joe
user //Average Joe
Have you researched existing solutions like RBAC? Whilst such a system would most likely be complete overkill for the particular nut you're trying to crack it would at least help to boost confidence that you're on the right track.
That aside, the general roles I'd expect would be along the lines of:
Administator - Total control of the system, can view logs (as you should be logging all changes), etc. plus...
Publisher - Can put content live plus...
Author - Can create content
However, how these roles are applied across the system is where things get tricky, as a specific user would presumably have different rights to different content areas/modules.
For most applications, so I think it'll be true for CMSs as well, my customers usually prefer a rights-oriented approach. Here is how it goes :
You list the main actions. In your CMS that would be : Create and edit content; Delete content; Classify/categorize content; Validate content; Publish content; Manage users; Etc.
You define what actions are allowed or denied for each user
To make things a little better, you can create several roles (Editor; Administrator) to make typical users creation easier (by pre-filling the form when a role is chosen).
I have a custom CMS built on the Zend Framework that uses Zend's ACL to extends some basic roles (so you can deny resources specifically for additional users or allow others to access resources they normally couldn't). My basic roles go from CMS users all the way down to website "members" as follows (I just use one users table to store all my authentication).
Developer
Edit any content, edit layouts, settings, configuration. Use special tools that can call shell scripts and force cron jobs.
Admin
Edit any content, edit layouts, settings.
Author
Edit content.
Member
Can view the login screen, forgot password and bug report.
Now, Zend has a nice ACL implementation so you can easily extends your base ACL class and add new roles that extend from the basic roles. So I might make an "Admin" who has access to one of the Developer tools (e.g. purge or cache management) or lock an author to only be able to manage blogs (and not for example news).
I wouldn't necessarily dismiss the fine grained control system you have now. If you have one that is adaptable focus on hiding away the complexity by providing a simplified interface (eg use the facade pattern or the adapter pattern). The benefits are that you provide users with the simplified version (simple permissions like 'admin' can 'delete' a 'post') while still retaining the fine grained features should you need them later (eg more complicated permission handling is to allow to delete posts when the post is your own post in category X). Then you can provide an alternative to the simplified version for that need in some places.
Admin : The one with all the rights
Author : The one who has all rights to a specific content (like a blog author who owns the blog), also has the permissions to add/invite users to collaborate/view the content
Collaborator : The one who can edit/add content to which the author has given rights, cannot delete the content or invite/add more collaborators
Viewer : The one who can view the content if the author has invited to view
Editors : The one who can approve/edit all types of content
Having a fine grain control is not a bad idea if you expect advanced users/developers to use the CMS. But for novice CMS managers, the basic roles make the system much more usable.
Administrator - can create users + all below
Editor - can edit posts of others + all below
Author - can write posts, edit own posts
Creator - responsible for creating and editing content.
Editor - responsible for tuning the content message
and the style of delivery, including translation and
localization.
Publisher - responsible for releasing the content for
use.
Administrator - responsible for managing access
permissions to folders and files, usually accomplished
by assigning access rights to user groups or roles.
Consumer, viewer or guest- the person who reads or
otherwise takes in content after it is published or
shared.