I am trying to redirect any logged user attempts to access /user.
In my module the next code to redirect after login:
function ccmm_user($op, &$edit, &$account, &$category = NULL)
{
switch($op){
case 'login':
$_REQUEST['destination'] = 'admin/';
break;
}
}
This is working. Then I try with case 'view': but it is useless.
It sounds like you want the user to never get to the /user page, whether on login or even by going there manually.
In that case you should do a simple check in a hook_init function like this:
function ccmm_init() {
if ( $_REQUEST['q'] == '/user' ) {
drupal_goto('/admin'); // Or where ever you want to send them
}
}
Of course there are a lot of checks you should do, and you may want to look into using the Global Redirect module, don't worry it's only 8k in size so the concern about adding yet another module is not such a problem in this case.
You could try the Login Destination module rather than writing your own code.
If you're not familiar with the Login Toboggan module, you should be.
A better way could be to use hook_menu_alter in your module to just remove the menu entry for /user/%user_uid_optional, or move it to another URL.
That way you won't only be handling just logins (as you currently do), but ANY access to /user/ (caveat: including those by the admin user). Or you could use the same hook to modify the access check and only grant it to users with higher permissions, like administer users
Related
http://localhost/drupal-9.3.3/user/372#myaccount
How to remove user id on URL . Please suggest how to change these type security isssue.
If you want to change the url structure to remove ids, use pathauto https://www.drupal.org/project/pathauto
You can choose to have an url structure for user profiles that can be generated from any user field.
Someone told me that everything you write on the front end or in your main folder is always just basically a suggestion a.k.a. not secure.
Good ways to secure site:
Authenticate users using backend like firebase read/write permissions
Use randomized urls / keys (which firebase also does)
Also catch exceptions and deal with them, perferably at the the place where that function is created, not when it is executed:
Example
yes:
function() => {
// do something
//catch error
}
function(); // call function;
No:
function().then(error => { //do something})
Currently building a WordPress intranet site, that authenticates users using Auth.0 SSO, against the company's Azure AD. The SSO functions properly, but I'm trying to get more granular with access control using Auth.0's "rules". The ideal result is a rule that specifies (updates) the user's WP Profile with a user role based on their job title from AD. The code below has been modified from one of Auth.0's rule templates, and runs clean. However, it doesn't work - I'm not sure what particular arguments/functions I need to actually update the role in WordPress. I'll be up-front and admit that I'm far from proficient in JS. Any thoughts?
function (user, context, callback) {
if (user.job_title === 'IT/Marketing Coordinator') {
user.vip = true;
}
callback(null, user, context);
}
In the example above, it successfully sets "user.vip" to "true" (which really doesn't prove much except that the rule executes without error.
this rule, as you said, is fine and will add this attribute.
The issue is that you will need to do something from the wordpress side to make it work (that the user has a vip flag doesn't mean anything to WordPress).
What you can do is hook to the auth0_user_login action that is fired each time a user logs in and based on the user profile set/change the user role.
This is how you hook to the action:
add_action( 'auth0_user_login', 'auth0UserLoginAction', 0,5 );
function auth0UserLoginAction($user_id, $user_profile, $is_new, $id_token, $access_token) {
...
}
I think you will find this WP doc useful to update the user role: https://codex.wordpress.org/Function_Reference/wp_update_user
For my Meteor application, I would like to have the following signup process:
User registers username, email and password. (He's not able to log in yet.)
Confirmation email sent [Accounts.sendEnrollmentEmail]
User confirms email [Accounts.onEnrollmentLink]
User is created. [Accounts.createUser] (He's able to log in.)
In order to achieve this, I feel like I would have to store the plain text password in a table of temporary users (step 1) in order to create the actual user later (step 3). Obviously this is a horrible idea.
I could of course only ask for the password as of step 3 and create the user at once - but it's not the behavior I would like to achieve.
So: Is there a proper way to store the password securely to later pass it to the user creation? Or is there a way to create a not-loginable users?
There is not much you have to do yourself as Meteor brings everything you need for save password storage when you create a user with the built in methods. So you should use these methods from the beginning (Your step 1: Accounts.createUser, step 2: Accounts.sendVerificationEmail, step 3: Accounts.verifyEmail, step 4 isn't necessary anymore).
Now to get where you want to be you can use an approach like David Weldon suggested but use Accounts.validateLoginAttempt on the sever side. That is a little easier and the login isn't allowed in the first place.
For example you could have this code server side:
Accounts.validateLoginAttempt(function(loginAttempt){
if (!loginAttempt.allowed) {
// Only tell the user that something went wrong but not what to enhance security
throw new Meteor.Error(901, 'Your login credentials are wrong. Try again.');
} else {
// In some cases this method isn't invoked with a correct user object...
if (!loginAttempt.user) {
throw new Meteor.Error(902, 'No valid user object. Make sure to validate your email address first.');
}
// If email verification is required check if the user has a valid email address and don't allow the login if he has none
if (!loginAttempt.user.emails[0].verified) {
throw new Meteor.Error(902, 'Your email address has to be verified first.');
}
// We have a correct login!
return true;
}
});
And now on the client side you can use a logic like this for the login
Meteor.loginWithPassword(email, password, function(callback) {
if (callback === undefined) {
// Your login logic
} else if (callback.error == 902) {
// Your "not verfied" logic
} else {
// Your other login errors logic
}
}
Note that you may have to adjust the registration process a little bit, too, as Meteor per default tries to login users directly after registration but this will not be possible anymore.
Also note that you may use Accounts.validateLoginAttempt for more than just that. For example you also could implement a logic here to only allow a certain amount of bad login attempts from the same IP.
We've used a slightly different pattern in our app based on the accounts package
User registers
User is logged in normally
Out main site template conditions content with
<template name="main">
{{#if currentUser}}
{{#if verified }}
...
{{else}}
Notice to user to look for their verification email
{{/if}}
{{/if}}
</template>
Based on a helper function
Template.main.helpers({
verified: function() { return Meteor.user().emails[0].verified; }
});
This meets the requirement that the user can't do much if anything until they have been verified yet uses the accounts package in a simple and secure way.
I could see taking a related approach using iron:router as well.
I had to add a WordPress installation to my CodeIgniter system, so I've put it in a submap called blog and excepted that folder in my .htaccess. All good and well.
I've put the all WordPress tables together with in my CodeIgniter databases with prefix _wp.
I've now loaded the WordPress blog header file into the index.php of CodeIgniter, like so;
require('blog/wp-blog-header.php');
add_filter('site_url', 'ci_site_url', 1);
function ci_site_url() {
include(FCPATH.'/application/config/config.php');
return $config['base_url'];
}
And made a registration method in my Account controller to make an actual link to my Customers. I do this because I want to make the WordPress login/registration obsolete and solely control that from the CodeIgniter login page;
protected function register_wp($email_address = FALSE) {
if ($email_address !== FALSE) {
if (username_exists( $email_address ) == NULL) {
$password = wp_generate_password(12, TRUE);
$user_id = wp_create_user($email_address, $password, $email_address);
wp_update_user(array(
'ID' => $user_id,
'nickname' => $email_address
));
$user = new WP_User($user_id);
$user->set_role('subscriber');
$login_data = array(
'user_id' => $user_id,
'password' => $password,
);
return $login_data;
}
else {
// User already exists with that email address
return FALSE;
}
}
else {
// No email_address given
return FALSE;
}
}
And the login method, to give an idea;
protected function login_wp($user_id = FALSE) {
if ($user_id !== FALSE) {
$user_login = 'admin';
$user = get_userdatabylogin($user_login);
$user_id = $user->ID;
wp_set_current_user($user_id, $user_login);
wp_set_auth_cookie($user_id);
do_action('wp_login', $user_login);
}
else {
// No user_id given
return FALSE;
}
}
All still going well. But here comes the clash; something I was very sad about because everything worked very well up until now:
WordPress overtakes the session and kills CodeIgniter's session.
I already tried tons of things;
session_rename('PHPSESSIDWP'); and then starting another session (with another name) for CodeIgniter after WordPress was loaded
COOKIE path (I'm not 100% sure if I done this right, as it didn't change at all. Read some things online it doesn't work well in all browsers either)
COOKIE domain (seemed to have no effect)
The problem is I can't load the require('blog/wp-blog-header.php'); only in the controller method, as I need to be able to control the logged in state of the WordPress part. Besides that I will get complaints about the site_url() function, that's already claimed by the URL helper.
I think the problem is mainly because both CodeIgniter and WordPress use their own unique way of handling Sessions (CI in the Database and WordPress in "super globals") which probably only makes them use the cookie to remember a "state".
My whole CodeIgniter system already runs on the Database-driven Session models so that's an absolute no-go to make a switch. For WordPress it seems it can't even work with session anymore with it's code features (I know session "do" work, but that doesn't seem to count in any way for the WP core system).
Also I quoted out wp_unregister_GLOBALS(); in the wp-settings.php file.
Plus that I also tried to rename my session COOKIE name in CodeIgniter to use something like session_ci
I really hope someone knows a way to being able to tell CodeIgniter or WordPress to only update their values and don't kill the whole session each time. I also read something about splitting up cookies with .htaccess but can't find good resources on it. So if anyone knows how to do that, I would be eternally grateful.
I'm in despair. Finishing it for 98% and then getting such a letdown in the end :(..
Update
Maybe I can do something in the WordPress section that handles the cookies?
http://codex.wordpress.org/Function_Reference/wp_set_auth_cookie
Sadly I'm not really home in the WordPress world. I solely have to use it this one time due to the bought template that the people really wanted to use in the blog.
Also this page states the following;
WordPress uses the two cookies to bypass the password entry portion of wp-login.php. If WordPress recognizes that you have valid, non-expired cookies, you go directly to the WordPress Administration interface. If you don't have the cookies, or they're expired, or in some other way invalid (like you edited them manually for some reason), WordPress will require you to log in again, in order to obtain new cookies.
I wonder tho, how to bypass that "invalid" check, which probably is the reason it kills the CodeIgniter cookie(s)? Weirdly enough tho, it seems the session_ci value stays, although the session still seems killed.
You need to put your session start at the very top of config.php.
This is the only place a session will not be destroyed by WordPress.
if (!session_id())
session_start();
If your PHP installation does not have register_global enabled, the
above code should allow you to use session, however, if it does, you
will not be able to get the data that was set in previous request.
This is because WordPress will destroy all data contained inside
session variable when it does the initialization.
Here's why and troubleshooting on this -> kanasolution.com
EXPANDED ANSWERS:
Source: http://codex.wordpress.org/WordPress_Cookies
On login, wordpress uses the wordpress_[hash] cookie to store your
authentication details. Its use is limited to the admin console area,
/wp-admin/
After login, wordpress sets the wordpress_logged_in_[hash] cookie, which indicates when you're logged in, and who you are, for
most interface use.
So WordPress clearly dislikes the way that you're writing cookies, maybe their lack of 8 pass MD5 hash etc? WordPress encryption methods
The WordPress Environment
The next thing I would try is integrating your custom login page into the WordPress environment instead of just requiring the header. (lets stay away from editing core)
From WordPress & AJAX by Ronald Huereca page 78 explains manually loading the WordPress environment.
The use of the dirname functions depend on the hierarchy of your file. Adjust them as needed. Code should be used before the tag of your file.
$root = dirname(dirname(dirname(dirname(dirname(__FILE__)))));
if (file_exists($root.'/wp-load.php')) {
require_once($root.'/wp-load.php');
/*Run custom WordPress stuff here */
//Output header HTML, queue scripts and styles, and include BODY content
wp_enqueue_script('my_script', get_stylesheet_directory_uri() . '/my_script.js', array('jquery'), '1.0.0');
wp_print_scripts(array('my_script'));
}
I want to redirect users when they log in to my site to a specific page. I currently do this in hook_user:
if($op == 'login') {
drupal_goto('defaut');
}
This mostly works fine. However, I'm using Ubercart to take orders, and have it configured to automatically log in new users. This happens before the conditional action to update the order status to "Completed" is triggered. This means that when the user is logged in automatically, my hook_user redirects the user, and bypasses the remaining order processing.
At the moment, I'm working around this by checking debug_backtrace for the calling function uc_cart_checkout_complete somewhere in the call stack, but this sounds like a really dirty way to resolve it.
Can anyone suggest a cleaner way to achieve my conditional redirection without hacking great chunks of Ubercart?
You can use hooks of ubercart (for example, hook_order, hook_cart etc of ubercart, see in ubercart\docs\hooks.php ), add $_SESSION['no_redirect'] = true; there, and change you redirection:
if($op == 'login' && !$_SESSION['no_redirect']) {
unset($_SESSION['no_redirect']);
drupal_goto('defaut');
}