ceberlin Posted November 8, 2014 Share Posted November 8, 2014 I have a tricky question with the roles. i have those roles -(guest) -user -editor -admin -superadmin For security reasons I want to allow the password reset only for people that are "users" but have no higher role. (An editor should ask the superadmin instead.) Is there an easy way to check whether a user has ONLY the role of "user", and nothing else? Link to comment Share on other sites More sharing options...
Macrura Posted November 9, 2014 Share Posted November 9, 2014 you mean like this? if( $user->hasRole('user') && !$user->hasRole('editor') && !$user->hasRole('admin') && !$user->hasRole('superadmin')) { //password reset stuff here } 2 Link to comment Share on other sites More sharing options...
gebeer Posted November 9, 2014 Share Posted November 9, 2014 When you create a user through the admin or through the API, it always gets assigned the guest role along with the custom roles that you assign. So if you assign a custom role "user", your user will have 2 roles: guest and user. Now you can check if a user has the role "user" and a total of 2 roles assigned. In PHP: if (count($user->roles) == 2 && $user->hasRole("user")) { //do stuff here } 3 Link to comment Share on other sites More sharing options...
Macrura Posted November 9, 2014 Share Posted November 9, 2014 @gebeer - nice one, ok i see how that would work, b/c the lowest level user will always have only 2 roles and that lowest role Link to comment Share on other sites More sharing options...
ceberlin Posted November 9, 2014 Share Posted November 9, 2014 if( $user->hasRole('user') && !$user->hasRole('editor') && !$user->hasRole('admin') && !$user->hasRole('superadmin')) { //password reset stuff here } Thanks Macrura. That would work and that is how I had it. Problem is that this would break my security concept the minute I change a role or add one - and forget to update this code afterwards. Now you can check if a user has the role "user" and a total of 2 roles assigned. In PHP: if (count($user->roles) == 2 && $user->hasRole("user")) {//do stuff here } gebeer, this is so brilliant! - exactly what I was looking for. And you come up with ideas like this at 3 in the morning? Link to comment Share on other sites More sharing options...
gebeer Posted November 9, 2014 Share Posted November 9, 2014 I'm in Thailand where it was 9 in the morning when 3 in the morning in Berlin. At 3am I was sound asleep Link to comment Share on other sites More sharing options...
Mass Harry Posted January 12, 2015 Share Posted January 12, 2015 create tutorial registeration from and login member Link to comment Share on other sites More sharing options...
quickjeff Posted March 8, 2015 Share Posted March 8, 2015 Hi Guys, So I have implemented Ryan's template setup for login, profile, logout and reset pass. My question is, what if we want to allow the user to login with the username or their email, which most forms do nowadays. Any advice on the approach. Essentially, 1 form, 2 input fields, 1 submit button. Here is the template being used to handle login as of now: if($user->isLoggedin()) $session->redirect('/profile/'); if($input->post->username && $input->post->pass) { $username = $sanitizer->username($input->post->username); $pass = $input->post->pass; $u = $users->get($username); if($u->id && $u->tmp_pass && $u->tmp_pass === $pass) { // user logging in with tmp_pass, so change it to be their real pass $u->of(false); $u->pass = $u->tmp_pass; $u->save(); $u->of(true); } $u = $session->login($username, $pass); if($u) { // user is logged in, get rid of tmp_pass $u->of(false); $u->tmp_pass = ''; $u->save(); // now redirect to the profile edit page $session->redirect('/profile/'); } } // present the login form $headline = $input->post->username ? "Login failed" : "Please login"; $page->body = " <h2>$headline</h2> <form action='./' method='post'> <p> <label>Username <input type='text' name='username'></label> <label>Password <input type='password' name='pass'></label> </p> <input type='submit'> </form> <p><a href='/reset-pass/'>Forgot your password?</a></p> "; include("./main.php"); // main markup template Link to comment Share on other sites More sharing options...
adrian Posted March 8, 2015 Share Posted March 8, 2015 Take a look at this thread: https://processwire.com/talk/topic/1838-login-using-e-mail-rather-than-username-and-general-login-issues/ There is a module for allowing login via email address, but be sure to read through the read, especially the posts by Ryan about potential issues with logging in via email. Link to comment Share on other sites More sharing options...
quickjeff Posted March 8, 2015 Share Posted March 8, 2015 Hey Adrian, I saw that post before posting here but ended realizing that the member was asking to replace the username. However, I want the user to either login using a username or their email. So basically, checking the input field for either one. Similar to what the temp_pass does. However, still haven't slapped together a solution. Thanks! Link to comment Share on other sites More sharing options...
adrian Posted March 8, 2015 Share Posted March 8, 2015 Sorry about that - good point. I think the problem with what you're trying to implement is that @ is not allowed in name fields. This is a bit hacky, but seems to work fine and allows a user to log in with either their name or email address. Keep in mind there will be issues if you have more than one user with the same email address - email is not a primary/unique fieldtype so even though there are checks to prevent a user from changing their email to one that already exists in the system, it is still possible to create two users with the same email via the admin panel if you are setting them up. It replaces any instances of "-" with "@" and checks to see if it can find the user with that email address. If there isn't a match, it processes the name with the "-" just in case there is a user in the system with a name that contains a "-", which is allowed. public function init() { $this->addHookBefore('Session::login', $this, 'beforeSessionLogin'); } public function beforeSessionLogin(HookEvent $event) { $name = $event->argumentsByName('name'); if (strpos($name, '-') !== FALSE) { $email = str_replace('-','@',$name); $u = wire('users')->get("email=$email"); $username = $u->id ? $user->name : $name; $event->setArgument('name', $username); } } I put this together pretty quickly, so can anyone think of any major issues with this? 1 Link to comment Share on other sites More sharing options...
quickjeff Posted March 8, 2015 Share Posted March 8, 2015 Hi Adrian, this seems to be for an admin login versus a front end login like I have setup. I included the snippet of code a couple posts above. Its the same setup Ryan created. Link to comment Share on other sites More sharing options...
Jan Romero Posted March 8, 2015 Share Posted March 8, 2015 $username = $sanitizer->username($input->post->username); $pass = $input->post->pass; $u = $users->get($username); if($u->id && $u->tmp_pass && $u->tmp_pass === $pass) { ... } $u = $session->login($username, $pass); This is where you try to find the user by the submitted name and then check if you got one by seeing whether $u->id is 0. So what you want to do is, if you didn’t find a user with that name, assume that an e-mail address was submitted instead, and check that: // Get user by the input name $username = $sanitizer->username($input->post->username); $pass = $input->post->pass; // (password is irrelevant for this, so we don't have to repeat it below) $u = $users->get($username); if ($u->id == 0) { // no user was found, so let's do the same thing, only // this time, treating the input as a mail address $usermail = $sanitizer->email($input->post->username); $u = $users->get("email={$usermail}"); // select by matching the mail field } // Now do the same checks as before and see if // the user was found after all if($u->id && $u->tmp_pass && $u->tmp_pass === $pass) { ... } // log in with $u->name, the name of the matched // account, instead of $username. If only the NullUser // was found, this will be an empty string. $u = $session->login($u->name, $pass); 2 Link to comment Share on other sites More sharing options...
quickjeff Posted March 9, 2015 Share Posted March 9, 2015 @Jan Romero, boom! Thank you for this. Greatly appreciate it. I set it up as mentioned and so far so good. Link to comment Share on other sites More sharing options...
adrian Posted March 9, 2015 Share Posted March 9, 2015 Hi Adrian, this seems to be for an admin login versus a front end login like I have setup. I included the snippet of code a couple posts above. Its the same setup Ryan created. Well actually, that hook and function I put together also works perfectly on the front-end, as well as the admin - I assumed you wanted both. All you need to go is use that as part of a module and then be sure to load the module in your login.php file for it to also work on the front-end. But if you only need front-end, then Jan Romero's version is simpler. 1 Link to comment Share on other sites More sharing options...
quickjeff Posted March 9, 2015 Share Posted March 9, 2015 @Adrian, yes your correct, I guess I overlooked at first. Thank you for the help as well!!! Link to comment Share on other sites More sharing options...
adrian Posted March 9, 2015 Share Posted March 9, 2015 No problem. Also, as a somewhat cleaner alternative to what I posted above, you can grab the POSTed version of the username directly to avoid the need to replace "-" with "@". With this version, it doesn't have to do anything if there is no "@" in the entered username. public function init() { if (strpos(wire('input')->post->login_name, '@') !== FALSE) { $this->addHookBefore('Session::login', $this, 'beforeSessionLogin'); } } public function beforeSessionLogin(HookEvent $event) { $name = wire('sanitizer')->email(wire('input')->post->login_name); $u = wire('users')->get("email=$name"); if($u->id) $event->setArgument('name', $u->name); } This way you can choose to sanitize it as an email address before it has been sanitized as a pageName which doesn't allow "@". The disadvantage to this version though is that for the front-end, you need to make sure your custom login form also uses "login_name" as the name of the input field. Not a big deal, but not as versatile I guess. 2 Link to comment Share on other sites More sharing options...
quickjeff Posted March 26, 2015 Share Posted March 26, 2015 Ryan had shown us a nice way to setup user front end login etc. I came across an issue with a client in which I have setup SMTP for a method of delivering notification emails. However, using Ryan's suggested /reset-pass/ page, the user is not getting notifications. Any light on enabling SMTP for the reset-pass page as well? Link to comment Share on other sites More sharing options...
adrian Posted March 26, 2015 Share Posted March 26, 2015 So long as you have one of the SMTP modules installed all you need to do is replace instances of mail() with wireMail() and they will be sent via SMTP. So, look in your reset-pass template code and make that change. Link to comment Share on other sites More sharing options...
quickjeff Posted March 26, 2015 Share Posted March 26, 2015 That makes sense, however, I just tested a formbuilder form and this is also the case, it is not using the SMTP I installed. Any advice here? Link to comment Share on other sites More sharing options...
adrian Posted March 26, 2015 Share Posted March 26, 2015 I am not a formbuilder user, but I know that support for wireMail and hence the ability to use one of the SMTP modules you need the beta version of formbuilder. How do you know it's not using the SMTP module - is it just that the emails aren't being received? Have you used the test functionality in those modules to make sure they are working? Have you tried manually calling wireMail() in a script to test the sending and receiving? Link to comment Share on other sites More sharing options...
quickjeff Posted March 26, 2015 Share Posted March 26, 2015 I have tested it. Just not with wireMail. Also just tried your suggested change and for some odd reason, I cannot send a user a reset password. Link to comment Share on other sites More sharing options...
hkbaliweb Posted September 4, 2015 Share Posted September 4, 2015 (edited) this source code registration member for processwire : <script type="text/javascript" src="/site/templates/scripts/register.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#registerform").validate({ debug: false, rules: { login_name: { required: true, minlength: 6, remote: "/process/username.php" }, login_pass: { required: true, minlength: 6 }, confirm_pass: { required: true, minlength: 6, equalTo: "#login_pass" }, email: { required: true, email: true, remote: "/process/emails.php" } }, messages: { login_name: { required: "Inserisci il tuo username", minlength: jQuery.format("Inserisci almeno {0} caratteri"), remote: jQuery.validator.format("Lo username {0} non è disponibile.") }, login_pass: { required: "Inserisci la password", minlength: jQuery.format("Inserisci almeno {0} caratteri") }, confirm_pass: { required: "Ripeti la password", minlength: jQuery.format("Inserisci almeno {0} caratteri"), equalTo: "Le password non sono uguali" }, email: { required: true, email: "Inserisci una email valida", remote: jQuery.validator.format("Questa email è già presente nel nostro database.") }, }, submitHandler: function(form) { $("#register_submit").attr('value','Attendi...'); $("#register_submit").attr('disabled', 'disabled'); $.post('/process/register.php', $("#registerform").serialize(), function(data) { if (data=='success'){ var url = "/mioprofilo/"; $(location).attr('href',url); }else{ $(".span16").prepend( $(data).hide().fadeIn('slow') ); $(".error").fadeOut(5000); $("#register_submit").attr('value','Iscriviti'); $("#register_submit").removeAttr('disabled'); } }); } }); }); </script> <div class="row"> <div class="span16"> <fieldset> <legend></legend> <form action='/iscrizione/' method='post' id="registerform"> <div class="clearfix"><label for="login_name">Username</label><div class="input"><input type="text" id="login_name" name="login_name" value="" maxlength="50" /></div></div> <div class="clearfix"><label for="login_pass">Password</label><div class="input"><input type="password" id="login_pass" name="login_pass" value="" /></div></div> <div class="clearfix"><label for="confirm_pass">Ripeti password</label><div class="input"><input type="password" name="confirm_pass" value="" /></div></div> <div class="clearfix"><label for="email">Email</label><div class="input"><input type="text" name="email" id="email" value="" maxlength="40" /></div></div> <div class="actions"> <input type="submit" value="Iscriviti" class="btn primary" name="register_submit" id="register_submit" /> </div> </form> </fieldset> </div> </div> <?php require_once('../index.php'); require_once('class.tempmail.php'); $input = wire('input'); $sanitizer = wire('sanitizer'); $roles = wire('roles'); if($input->post->register_submit) { $username = $sanitizer->username($input->post->login_name); $pass = $input->post->login_pass; $email = $sanitizer->email($input->post->email); $u = new User(); $u->name = $username; $u->pass = $pass; $u->email = $email; $u->roles->add($roles->get("guest")); $u->roles->add($roles->get("utente-basic")); // my custom role $u->save(); // i add profile picture to every user after registration using 5 different random avatar images. $pnum = rand(0,5); $profilephoto = wire('config')->paths->root."site/templates/styles/images/noprofile".$pnum.".jpg"; $u->profilephoto->add($profilephoto); $u->profilethumb->add($profilephoto); $u->save(); if (wire('session')->login($username, $pass)){ $array_content[]=array("username", $username); $array_content[]=array("login", $username); $array_content[]=array("password", $pass); $admin_id = "noreply@domain.com"; $user_email = $email; sendingemail_phpmailer($array_content, "register.html","class.phpmailer.php","Sitename",$admin_id,$user_email,"Welcome to website"); print "success"; }else{ print '<div class="alert-message error"> <p>Errore durante la registrazione. Riprova.</p> </div>'; } } ?> Edited September 5, 2015 by Martijn Geerts Removed links to a website (spam) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now