I am having tons of fun working on a big project that was, for reasons hard to justify, based on Joomla! (which I don't mean to criticise, Joomla! is great, just not for the task I am faced with currently) and when I googled for a way of determining whether the currently logged-in user is an Admin, I found a post that quite boldly recommends using the following code:
$user =& JFactory::getUser();
if($user->usertype == "Super Administrator" || $user->usertype == "Administrator"){ ... }
To me, this looks like a rather strange way of checking for Admin users. I would appreciate a $user->isAdmin() method to do this rather than a couple of hard-coded strings.
I fail to find a more elegant solution to checking for admin users within the Joomla! framework. Can anyone help?
Actually, as the Access levels are hard coded into the database in Joomla! 1.5, the only way this string comparison could fail is when someone deliberately hacked new groups into it. Strings can be changed in the .ini-Files (so that non-english installations still use the english words in the database - this is not true for other tables like the names of plugins or components.)
You could get the group id via JFactory::getACL(), and then $acl->getGroupsByUser($userid, false) (see docs), but assuming that a greater id means greater privileges as well, seems a bit hacky, too (though true for a standard installation).
Other than that, you could take over a Joomla! capability: define more explicitly, what a "admin user" is: someone who can install new software? who can change the system's configuration? Just make a reasonable assumption, something related to what you want him to do as a admin user, use it in a authorize()-Call (see docs), and maybe document it in your interface.
The only clean solution (that I know of) would be to define new entries for the ACL-authorize-lookuptable (currently implemented in php only, not SQL). This is the only way to ensure that it will be Joomla! 1.6-proof, where custom user groups will be possible (and so the admin user can choose to give this authorization to a user group or not). For example:
$acl =& JFactory::getACL();
$acl->addACL('{com_nameOfExtension}', '{action}', 'users', 'super administrator');
$acl->addACL('{com_nameOfExtension}', '{action}', 'users', 'administrator');
And there we have them again, hard-coded groupnames. Well.
Peter,
I concur on the joomla sentiments, we use .net/php here as well and have a few projects that were started on joomla for some unknown reason !!
amnyway, another finer grained approach may be to examine the actual rights that the user has, rather than them being suoper admin etc. you can get to this info along the following lines:
$user =& JFactory::getUser();
if ($user->authorize('com_content', 'edit', 'content', 'all')) {
echo "<p>You may edit all content.</p>";
} else {
echo "<p>You may not edit all content.</p>";
}
if ($user->authorize('com_content', 'publish', 'content', 'own')) {
echo "<p>You may publish your own content.</p>";
} else {
echo "<p>You may not publish your own content.</p>";
}
i know it's still hardcoded but at least it's user specific, rather than priviledge specific. this approach does however allow you to target specific 'component' related priviledges, so might be useful for you.
I'll track the replies to see if there's a 'proper' answer as it definately is an omission.
jim
The following could be a hack on Joomla. I tried it and got worked.
Take the case of sessions
$_SESSION[__default][user]->usertype;
This will give the type of user logged in you can use this in any conditional statements
You can check 'assigned user groups' of the logged in user using getUser() function.
$user =& JFactory::getUser();
$assigned_usergroups = $user->groups; // Array of assigned User Group
if (in_array(8, $assigned_usergroups)) {
echo "Super Admin";
}
else if (in_array(7, $assigned_usergroups)) {
echo "Admin";
}
else {
echo "Other"; //Any of Guest/Public/Others
}
You can see the following snapshot of the Joomla's predefined IDs for each User Group in the Database:
Snapshot here
If ur joomla administrator username is admin then u can use below code aspeter described before
$user =& JFactory::getUser();
if($user->usertype == "Super Administrator" && $user->username == "admin")
{
//... do what ever
}
Related
I'm trying to set up customer error messages for different user groups in Joomla 3.6. We have locked content on the front-end of our site, currently there is a generic message that tells the user to login to see it, however we recently adjusted our user groups to create multiple levels of access so even after logging in there may still be content the user can't see. In those instances I need to be able to show a message specific to that user group rather than a generic "please login".
I have used Language Overrides for custom messages before but there's no option I've found to have it show to specific groups. I don't know a lot about code, and Google revealed no existing answers for this.
This might be something to get you going:
$groups = JUserHelper::getUserGroups((int) $user->user_id);
if(in_array(8, $groups))
{
$level = 'admin';
} elseif (in_array(4, $groups)) {
$level = 'globalmoderator';
} elseif (in_array(3, $groups)) {
$level = 'moderator';
} elseif (in_array(2, $groups)) {
$level = 'user';
} else {
$level = 'guest';
}
Without some programming it'll not be easy for you to achieve. But in short, you can create a pretty simple plugin, which will capture certain Joomla events.
For example, Joomla has onUserLogin even, which allows you to do different stuff, when user logs in. Your custom plugin can capture this even, check for some parameters and then add a group specific message to the queue. More over, you can get current message queue, parse or empty it and then add group specific message.
You can do the same for any other Joomla event like onUserLogout, onUserLoginFailure and so on. There're plenty events to choose from.
As for message specific groups, you can add your own generic messages similar to this:
COM_USERS_ERROR_LOGIN_GUEST
COM_USERS_ERROR_LOGIN_REGISTERED
COM_USERS_ERROR_LOGIN_ADMIN
Then you just take "COM_USERS_ERROR_LOGIN_" string and add a group name (or ID, when language is non-English) to it. That's it.
The task doesn't seem too complex, but you still have to know some coding to create a plugin, which will capture Joomla events. There's no other way to do this.
Try to use articles for messages and filter it with permissions for user groups.
After some searching, I succesfully installed the Authority-l4 package to use for my Laravel project. The docs are clear but small (not much info/examples). This is what my config file looks like atm:
return array[
'initialize' => function($authority) {
$user = $authority->getCurrentUser();
$authority->addAlias('manage', ['create', 'read', 'update', 'delete']);
if($user->hasRole('admin')) {
//Admin can manage all resources
$authority->allow('manage', 'all');
}
// User can manage his own post
Authority::allow('manage', 'User', function($self, $user){
return $self->getCurrentUser()->id === $user->id;
});
// User can manage his own post
Authority::allow('manage', 'Post', function($self, $post){
return $self->getCurrentUser()->id === $post->id;
});
}
];
I have some questions about this:
How to add a role to a user? hasRole() exists, why not setRole()?
I noticed nothing gets saved into the database, isn't this better?
How do I use my database with Authority? Could someone give me a head start, I've been strugling four hours now.
In some articles they say that the class Role should be changed to have many permissions instead of a user having many permissions, isn't this better?
Probably I'm thinking way to difficult about this package, searching the internet doesn't help either. Any help is appreciated!
I'm the author of Authority, and I maintain Authority-l4 though it was written primarily by Conar Welsh.
Since roles, as defined in the package, are just an Eloquent relation so you can simply add them like any other relation in Eloquent.
I have no idea what you're asking here, can you rephrase?
Can you elaborate on the question beyond what's in the readme (the part just above General Usage)?
Probably - either works. You don't need to use this structure to use Authority-l4. It's just an optional structure that you are 100% free to setup as you'd like. I personally don't use this at all and just use the Authority facade that it generates. Most of my permissions aren't stored in the DB though so that plays a factor.
The idea behind Authority is that it is implementation agnostic. It genuinely does not care where you store your data, you just need to tell authority what to do with your rules. Reading the section of the readme referenced above and the readme on the Authority core repo should be able to give you a general idea of how it expects information to be loaded - anything beyond that is up to your discretion.
I've created a couple of pages they are users, groups and permissions.
I would like the admin to be able to create groups and set what those groups can do via the permissions page.
So on the permissions page I would have a list of things a user could do e.g.: add content, delete content.
And if I check the add content box then the group can only add content and not delete content.
The problem I'm having is that I don't know where to go to look for information on how to go about it. I've already got my database set up and I'm thinking maybe sessions and routes is the way to go, but I'm not sure.
Frameworks is the way to go for something this complex. I'm working on a very similar project for my work (a dashboard to do different things based on User Role/Permissions) and I found it incredibly difficult to manage without the use of a framework. I would highly recommend Cartalyst/Sentry for this. It turns complex database operations like checking permissions, update permissions, creating groups etc into simple one. Here is a link to the manual:
Cartalyst/Sentry
It has a database backend already created (and modifiable) for you, so you simply follow the installation instructions and go over the documentation to get a better understanding. In your example, it would be as simple as creating a group and it's permissions:
// Define permissions (1 is allowed, 0 is not allowed)
$permissions = array('content.create' => 1, 'content.delete' => 1, etc etc...));
$group = Sentry::createGroup(array('name' => 'Admin', 'permissions' => $permissions));
Creating a user and adding them to the group:
$user = Sentry::createUser(array('email' => 'test#test.com', 'first_name' => ..., etc));
$group = Sentry::findGroupByName('Admin');
$user->addGroup($group);
And then checking their permissions during routing:
$user = Sentry::check(); // Aka get the current user.
if($user->hasAccess('content.create'){
// Continue
} else {
// Redirect to error page, etc
}
Now that's a brief overview of the system, and I assume you know how to use controllers and routes, but play around with it and I'm sure you'll come to see how powerful this Framework is when working with Laravel.
Hope that helps!
Then checking whether or not a user
I have a payment gateway integrated on my website. When user is done with payment he/she is redirected to a particular page say www.example.com/redirect. I want to prevent users from directly entering this url (www.example.com/redirect) in address bar and access the page. I want it asap.
Actually the page is protected from guest users but if logged in user types that url then it will redirect him to that page and hence the payment option will be skipped. I want the user must pay the amount first and then redirected to this page.
Hard to answer precisely since you only give a non-joomla url as an example, but at the top of every Joomla script is the following line:
defined('_JEXEC') or die( 'Restricted access' );
You obviously can't prevent a user from typing in the url, so this will at least detect if a session is already in place. If the user isn't in an active Joomla session, this will fire and prevent access. You could easily adapt it to do whatever you want to happen for your requirement, depending on whatever you have to check with, i.e. if the referrer is your payment gateway, etc.
I had a similar desire. I wanted the page to only display if the users was logged in and if they had filled out the order entry page.
What I decided to do was check to see if there was data in the POST.
controller/place_order.php (snipet)
public function submitOrder()
{
$post = JRequest::get('post');
$model = $this->getModel();
if($post != null && $post != ''){
if($model->placeOrder()){
}
}
JRequest::setVar('layout', 'submitOrder');
parent::display();
}
This prevents the task from executing my placeOder function anything in the model. Then I just add something similar to the submit order page. In your case "redirect".
view/place_order/tmpl/submitOrder.php (snipet)
defined('_JEXEC') or die('Restricted access');
$user =& JFactory::getUser();
if ($user->guest) {
echo "<p>You must login to access this page.</p>";
}
else if($_POST == "" || $_POST == null){
echo "<p>You can not directly access this page.</p>";
}else {
//Your order was submitted successfully HTML (don't forget to close it at the bottom ;)
There are a lot of ways you could do it... you probably don't even need to check in the controller if you don't want to but I do to save on time. With out seeing your code it's hard to tailor the answer but if you grasp the concept here it should help (I hope...).
You might also want to check out this page from Joomla on authorization and privileges.
this should be done in your component's base controller (controller.php). if you look at this code snippet:
// Check for edit form.
if ($vName == 'form' && !$this->checkEditId('com_weblinks.edit.weblink', $id))
{
// Somehow the person just went to the form - we don't allow that.
return JError::raiseError(403,
JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id));
}
this block of code is present in most of core components intended to do exactly what you want. how ever how this actually dos what it does is explained through the $this->checkEditId() function. I hope you are familiar with the JControllerForm class and if you are not check out the API. because creating an edit id for a page and "authorizing user for access to a specific page based on his last page" is done by JControllerForm.
I want to extend Ion Auth to only allow certain email addresses to register.
I'm fairly sure I could hack this together and get something working, but as a newbie to codeigniter and ion auth I wish to find out if there is a "proper way" to be doing what I need?
For instance can I "extend" ion auth (so I can update ion auth core files without writing over my changes?).
I noticed there are also hooks including this one (in the register function):
$this->ci->ion_auth_model->trigger_events('pre_account_creation');
Where do these resolve and can I use this one in order to intercept registrations from email addresses which don't match a list of those I wish to register?
If so, how would I do it? I would need access to the $email variable from the register() function.
Or is it just a case of altering the base code from ion auth and not updating it in the future?
Thanks for any help you can give me. Don't worry about the email bit, I'm capable of working out whether an email address matches the required email domains, I'm more interested in what is the best way to go about extending the library.
Tom
EDIT: Hi Ben, thanks for your answer, and thanks for taking the time to have a look at my issue. Unfortunately this hasn't helped.
I guess what you're trying to do there is add a little bit to the sql query a "where in" clause? I guess that the where in bit is incorrect as there isn't a column name.
Also, at this point I can't modify the sql query satisfactorily to produce the required output. e.g. I can add a hook to a function which is literally $this->db->where('1=1') and this outputs this sql in the next query:
SELECT COUNT(*) AS `numrows` FROM (`users`) WHERE `1=1` AND `email` = 'rawr#rawr.com'
The AND email = 'rawr#rawr.com' bit will always still return no rows. It should be OR email = 'rawr#rawr.com', but without editing the Ion Auth core code then I won't be able to change this.
I am starting to suspect (from the last couple of hours of tinkering) that I may have to edit the ion auth core in order to achieve this.
Check out this example: https://gist.github.com/2881995
In the end I just wrote a little form_verification callback function which I put in the auth controller of ion_auth which checked through a list of allowed domains. :)
When you validate your form in the auth controller you add a callback:
$this->form_validation->set_rules('email', 'Email Address', required|callback_validate_email');
You create a method in the controller called validate_email:
function validate_email() {
if (strpos($this->input->post('email'), '#mycompany.com') === false) {
$this->form_validation->set_message('validate_email', 'Not official company email address.');
return false;
} else return true;
}
This will cause the creation of the user to fail, since all rules must pass. You also provide an error message. Just make sure to have this line on the form view side:
echo validation_errors();