Grails spring-security-ldap plugin change user password for AD - grails

I have a grails application (2.5.0) using Spring security and authenticating with the spring-security-ldap plugin (2.0-RC2) against a windows AD domain.
This works very well to authenticate but now I have the requirement to allow the user to change their password (in fact to require it!).
Despite searching through the documentation, Reading the code and searching with google All I can find is references to LdapUserDetailsManager.changePassword but I cannot find a single example of how to use this.
I find in the plugin
public class GrailsLdapUserDetailsManager extends LdapUserDetailsManager
implements GrailsUserDetailsService {....
but this does not have the changePassword and I do not understand how to call it if it did.
I have looked through all the StackOverflow questions such as
how to change password using spring ldap and spring security
but the answers appear to be written in some other language and talk about things I do not have like xml files.
Can someone tell me, preferably with an understandable example how I can implement a change Password feature in Grails against an ldap AD source in conjunction with the grails spring-security-ldap plugin? Authentication without the ability to manage changing the passwords is just wrong!

You can make use of the ldapUserDetailsManager by injecting into your controller e.g.
gsp:
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<title><g:message code="menu.item.change.password" /></title>
</head>
<body>
<div class="maincontentdiv" role="main">
<div class="alert alert-info alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
flash.changePasswordMessage
</div>
<h3><g:message code="menu.item.change.password" /></h3>
<g:form class="form-horizontal">
<div class="form-group">
<label class="col-md-4 control-label" for="currentPassword">Current password</label>
<div class="col-md-4">
<g:field type="password" name="currentPassword" class="form-control" required="true" />
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="newPassword">New password</label>
<div class="col-md-4">
<g:field type="password" name="newPassword" class="form-control" pattern=".{6,15}" required title="Password must be a minimum of 6 and a maximum of to 10 characters" />
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="confirmNewPassword">Confirm new password</label>
<div class="col-md-4">
<g:field type="password" name="confirmNewPassword" class="form-control" pattern=".{6,15}" required title="Password must be a minimum of 6 and a maximum of to 10 characters" />
</div>
</div>
<g:render template="/templates/generic_submit_button" model="[btnname: 'changePassword', btntxt: 'Change password']" />
</g:form>
</div>
</body>
</html>
Controller:
class ChangePasswordController {
def ldapUserDetailsManager
def index() {
if ( params.changePassword ) {
try {
if ( params.newPassword.equals( params.confirmNewPassword ) ) {
ldapUserDetailsManager.changePassword( params.currentPassword, params.newPassword )
}
else {
throw new InvalidParameterException( 'Please ensure the new password and confirm new password fields match' )
}
}
catch( all ) {
flash.changePasswordMessage= all.message
}
}
}
}

Related

Rails devise two separate registration forms

I am building a Doctor booking platform where there's a patient and a doctor.
I currently have standard devise setup with one user model and one signup form, I want to have to separate forms one for patient where I will pass params role of patient and a doctor form with params of doctor role so I can assign roles from the controller or the model.
The forms will be quite the same only for doctor I will require some extra fields.
Also my doctor as it belongs to a user will have the ability to book an appointment with other doctors, is it a good practice to use boolean to define whether it's a doctor or not or use roles with enum.
I need help please
What about hidden_field_tag, did you have tried anything or want to clear concept? You can do this using hidden_field_tag like if you create those form using bootstrap tab like this
$('#myTabs a').click(function (e) {
e.preventDefault()
$(this).tab('show')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Doctor</li>
<li role="presentation">Patient</li>
</ul>
<h2>Just example form</h2>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
<h2>Doctor?</h2>
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
<div role="tabpanel" class="tab-pane" id="profile">
<h2>Patient?</h2>
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
in the form, you can just use a hidden field like when form for doctor
<%= f.hidden_field :role, value: "doctor" %>
and when form for Patient
<%= f.hidden_field :role, value: "patient" %>
and permit their role in the application_controller
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :role])
end
I thing it will help.

How to customize Spring Security Shiro Grails plugin Login Logout functionality?

This seems like something that should be pretty easy, but I am unable to customize the Login (login/authenticate) and Logout functionality of spring-security-shrio that is pre-built.
I would like to do things like add a login counter, or login log so when a user logs in I log who they are and additional information like an ip address.
Also, I went to the source and found the LoginController, copied that but noticed that there is no authenticate method within that controller.
I am upgrading an application from Grails version 2.4.4 to Grails 3+. Where is the code that is generated? Any guidance would be most appreciated.
Not Shiro specific but you can add a login directory to views then add your own auth.gsp to handle logging in.
Note that a number of the parameter names changed from Grails 2 to 3 e.g. j_username to username see here.
Here's a bootstrap styled one I converted from a Grails 2 to 3 app recently:
<html>
<head>
<meta name='layout' content='main'/>
<title><g:message code="springSecurity.login.title"/></title>
</head>
<body>
<div id='login' class="maincontentdiv">
<g:render template="/templates/alerts"/>
<form action='${postUrl}' method='POST' id='loginForm' class='form-horizontal' autocomplete='off'>
<fieldset>
<legend><g:message code="springSecurity.login.header"/></legend>
<div class="form-group">
<label class="col-md-4 control-label" for="username">
<g:message code="springSecurity.login.username.label" default="Username" />
<span class="required-indicator">*</span>
</label>
<div class="col-md-4">
<input type='text' class='form-control' name='username' id='username'/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="password">
<g:message code="springSecurity.login.password.label" default="Password" />
<span class="required-indicator">*</span>
</label>
<div class="col-md-4">
<input type='password' class='form-control' name='password' id='password'/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="submit"></label>
<div class="col-md-4">
<input type='submit' id="submit" class='btn btn-primary' value='${message(code: "springSecurity.login.button")}'/>
</div>
</div>
</fieldset>
</form>
</div>
<script type='text/javascript'>
<!--
(function() {
document.forms['loginForm'].elements['username'].focus();
})();
// -->
</script>
</body>
</html>

When using Angular.js, how to retain form data after submit?

I have used the basic angular script which update what ever you type in the input field on any element we specify, real time...
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
</body>
</html>
Im new to Angular. I used this on may rails app. But the problem is, the field I used ng-model will reset its valu after submit. Even setting the 'value' attribute won't work. How can I fix this?
Exact code generated from my rails application :
<form accept-charset="UTF-8" action="/members" class="custom" id="new_member" method="post">
<div class="row collapse text-field">
<div class="small-4 columns">
<h3>Add Member : </h3>
</div>
<div class="small-6 columns left inline">
<h3 class="subheader inline"> {{newEntry.name}}</h3>
</div>
</div>
<div class="row collapse text-field">
<div class="small-3 columns">
<label class="prefix" for="member_name">Full Name</label>
</div>
<div class="small-7 columns left">
<input class="input" id="member_name" name="member[name]" ng-model="newEntry.name" type="text" value="gj" />
</div>
</div>
<div class="row collapse text-field">
<div class="small-3 columns">
<label class="prefix" for="member_address">Address</label>
</div>
<div class="small-9 columns">
<textarea class="input" height="115" id="member_address" name="member[address]">
</textarea>
</div>
</div>
<div class="row">
<div class="small-9 columns" ><input class="button radius" name="commit" type="submit" value="Add Member" /></div>
</div>
</form>
Note : I haven't used an ng-controller. Im new to Angular. If its required, please tell me how to convert the above to the controller. I can get the value of the field and send it back to the form in rails. Its there in a variable. But Angular keeps wiping it!
Note2 : This problem persist only for the input field I used angular-model.. All the other fields retained the data!
Ok this is not the best solution but you could do this:
<input type="text" ng-init="yourName = 'Your Value Goes Here'" ng-model="yourName" placeholder="Enter a name here">
ng-init directives are run when the app intialises, so your value will be assigned to angular's internal "yourName" model and be updated in the view accordingly.
That would solve your problem but its not the best way. Hopefully that will get you going for now - I'll try and post a more "ideal" solution shortly.

How to handle Twitter Bootstrap fields with Thymeleaf Spring and less code

I need some advice how is a recommended way to handle Twitter Bootstrap fields with Thymeleaf. I know that recommendations are not so easy, so I wrote my thoughts about it and hope you can comment it. At the end there a some concrete questions.
First I tried a fragment which shows what is needed to generate
<div th:fragment="textfield">
<div class="control-group"
th:classappend="${#fields.hasErrors('__${fId}__')}? 'error'">
<label class="control-label" th:for="${fId}"
th:text="#{model.__*{class.simpleName}__.__${fId}__}+':'">
FirstName
</label>
<div class="controls">
<input type="text" th:class="${inputclass}" th:field="*{__${fId}__}" th:disabled="${disabled}"/>
<span class="help-inline" th:if="${#fields.hasErrors('__${fId}__')}"
th:errors="*{__${fId}__}"></span>
</div>
</div>
</div>
which can be used with
<div class="control-group replace" th:include="templates::textfield" th:with="fId='userId'" th:remove="tag">
<label class="control-label replace">Benutzer-Id</label>
<div class="controls replace">
<input type="text" value=""/>
</div>
</div>
or in short
<div class="control-group replace" th:include="templates::textfield" th:with="fId='userId'" th:remove="tag"/>
It's not very flexible about the input, so you need for a checkbox an own fragment.
Next I choose the layout-approach:
<div layout:fragment="bsfield">
<div class="control-group" th:classappend="${#fields.hasErrors('__${fId}__')}? 'error'">
<label class="control-label" th:for="${fId}"
th:text="#{model.__*{class.simpleName}__.__${fId}__}+':'">
FirstName </label>
<div class="controls">
<span layout:fragment="bsinput" th:remove="tag">
<input type="text" class="replace" th:field="*{__${fId}__}" th:disabled="${disabled}"/>
</span>
<span class="help-inline" th:if="${#fields.hasErrors('__${fId}__')}"
th:errors="*{__${fId}__}"></span>
</div>
</div>
</div>
Which is very flexible because I can define my input directly.
I can use it shortly with
<div layout:include="templates::bsfield" th:with="fId='firstName'" th:remove="tag">
<div layout:fragment="bsinput">
<input type="text" th:field="*{__${fId}__}" th:disabled="${disabled}"/>
</div>
</div>
or more prototype style
<div class="control-group" layout:include="templates::bsfield" th:with="fId='lastName'" th:remove="tag">
<label class="control-label" th:remove="all">Last Name</label>
<div class="controls" th:remove="tag">
<div layout:fragment="bsinput">
<input type="text" th:field="*{__${fId}__}" th:disabled="${disabled}"/>
</div>
</div>
</div>
Both variants has still a lot of boilerplate. So I think about the following solution inspired by Playframework helper.
<input type="text" th:bsfield="firstName" th:disabled="${disabled}"/>
and writing a Processor which creates
<div class="control-group"
th:classappend="${#fields.hasErrors('${fId}')}? 'error'">
<label class="control-label" th:for="${fId}"
th:text="#{model.__*{class.simpleName}__.${fId}}+':'">
FirstName </label>
<div class="controls">
<input type="text" th:class="${inputclass}" th:field="*{${fId}}" th:disabled="${disabled}"/>
<span class="help-inline" th:if="${#fields.hasErrors('${fId}')}"
th:errors="*{${fId}}"></span>
</div>
</div>
and replace ${fId} with the value of bsfield in this example "firstname". After that Thymeleaf should recompute it (setRecomputeProcessorsImmediately (true);) For the prototype I think it's necessary to write a JS-Solution.
I'm unsure if this is really clever or a misuse of Processors. Furthermore I'm unsure how much time a beginner need to write such a processor. Are 4 hours realistic or more a few days?
Would appreciate if someone can give me a hint.
In the meantime I did it. As a beginner you must calculate 4-8 hours, without JUnit tests (it looks difficult to test processors) and DTD and editor-support. The most problems I had was that it's difficult to reuse an existing node after changing attributes. Here it's better to clone it.
Next time I think I can do it in 1 or 2 hours.
The experience is very good, you have clean and short code. With the JS-File you don't lose the prototyping experience.

how to put login form # center of screen

I am developing MVC 3 application along with it I am using bootstrap for design.
I have created the log in form.
I am trying to set it at center position of the screen but some how its not working.
This is my code.
#using (Html.BeginForm("LoginUser","Login",FormMethod.Post))
{
<div class="container-fluid" style="padding-left:0px; margin-top:165px; margin-left:140px;">
<div class="row-fluid">
<div class="span12 roundedDiv offset4" style="width:400px; height:250px;">
...
...
...
Controls...
....
....
</div>
</div>
</div>
}
what to do ?
Margin auto does this for you, without having to use <center>.
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<style type="text/css">
#loginBox {
margin: 20% auto;
width: 200px;
}
</style>
</head>
<body>
<form action="index.php" method="POST" id="loginBox">
<input type="text" name="user" placeholder="Username" autocapitalize="off" /><br />
<input type="password" name="pass" placeholder="Password" /><br />
<input type="checkbox" name="remember"> Remember Me<br />
<input type="submit" value="Log In" name="login" />
</form>
</body>
</html>
I would advise against usage of margins for the horizontal alignment. Try something like this:
<div class="container-fluid">
<div style="margin-top:20px;" class="row-fluid">
<div class="offset4 span4 well">
<h1>Login page</h1>
<form method="POST">
<label>Login:
<input type="text" placeholder="Enter your login" name="username" autofocus class="span12">
</label>
<label>Password:
<input type="password" placeholder="Enter your password" name="password" class="span12">
</label>
<hr>
<div class="btn-toolbar">
<button type="submit" class="btn btn-info">Log in</button>Sign in with Google
</div>
</form>
</div>
</div>
This is code I used to build a simple login form.
Since you're using fluid container hence responsive design I'd recommend to avoid using hardcoded values like 400 px. Instead you can set it width by applying span class like:
<div class="row-fluid">
<div class="offset3 span6">
It gives you login form width of 6 rows and 3 rows offset on the left and right (12 rows is default bootstrap grid).

Resources