Play framework bind from request constructor - playframework-2.1

I'm having trouble when binding data from form, my User class has a constructor which hashes the password, the problem is that if I get the user from the form the password is stored as plain text.
My User constructor:
public User(String username, String completeName, String password,
String email) {
this.username = username.toLowerCase();
this.email = email;
this.registrationDate = new Date();
this.completeName = completeName;
try {
String[] passAndSalt = PasswordHash.createHash(password).split(":");
this.salt = passAndSalt[0];
this.password = passAndSalt[1];
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
My Controller:
public static Result addUser() {
Form<User> userForm = Form.form(User.class).bindFromRequest();
if (!userForm.hasErrors()) {
User formUser = userForm.get();
formUser.save();
return redirect(routes.Application.index());
} else {
return badRequest(registerUser.render(userForm));
}
}
I could hash the password before saving the user, but I was wondering if there is a way for Play to use the constructor I defined.
Using Play! version 2.1.1

Related

How to configure MailKit without password

In ASP.NET Core 6 Web API, I am using MailKit for Email configuration. I am using the SMTP server of my company which doesn't need a password.
I have this:
public class MailSettings
{
public string SmtpServer { get; set; }
public string SenderName { get; set; }
public string SenderEmail { get; set; }
public int SmtpPort { get; set; }
}
Since I am using my company SMTP configuration that needs no password, I use this method to send mails:
public async Task<bool> SendEmailAsync(MailRequest mailRequest)
{
var email = new MimeMessage { Sender = MailboxAddress.Parse(_mailSettings.SenderEmail) };
email.To.Add(MailboxAddress.Parse(mailRequest.ToEmail));
email.Subject = mailRequest.Subject;
var builder = new BodyBuilder();
if (mailRequest.Attachments != null)
{
foreach (var file in mailRequest.Attachments.Where(file => file.Length > 0))
{
byte[] fileBytes;
await using (var ms = new MemoryStream())
{
file.CopyTo(ms);
fileBytes = ms.ToArray();
}
builder.Attachments.Add((file.FileName + Guid.NewGuid().ToString()), fileBytes, ContentType.Parse(file.ContentType));
}
}
builder.HtmlBody = mailRequest.Body;
email.Body = builder.ToMessageBody();
try
{
using var smtp = new SmtpClient();
smtp.Connect(_mailSettings.SmtpServer, _mailSettings.SmtpPort, SecureSocketOptions.StartTls);
smtp.Authenticate(_mailSettings.SenderEmail);
await smtp.SendAsync(email);
smtp.Disconnect(true);
return true;
}
catch (Exception e)
{
_logger.Error(e, e.Source, e.InnerException, e.Message, e.ToString());
return false;
}
}
I got this error:
Argument 1: cannot convert from 'string' to 'MailKit.Security.SaslMechanism'
and it highlights this line of code:
smtp.Authenticate(_mailSettings.SenderEmail);
Expecting me to do it this way:
smtp.Authenticate(_mailSettings.SenderEmail, _mailSettings.Password);
How do I resolve this without password?
Thanks

Using Dropwizard Authentication manual

I'm currently using http://www.dropwizard.io/1.1.0/docs/manual/auth.html# Dropwizard-Authentication in my Application. But i like to do the authentication "manualy" which means from a specific login/logout API call on a not authenticated REST interface.
Is there any possibility to forward an REST Call to the Authentication?
#POST
#Path("login")
#Consumes(MediaType.APPLICATION_JSON)
#Timed
#UnitOfWork
public Optional<LoginResponse> login(LoginRequest request) {
// TODO forward login request to authentication
return null;
}
Thx in advance
Thx for helping me. I found a solution like that:
Adding an Authenticator to the REST Client
client = ClientBuilder.newClient();
authenticator = new Authenticator();
client.register(authenticator);
Setup the Authenticator on Login-Successfull
final UserAPIResponse response = create(request, UserAPI.PATH_ATTRIBUTE_DEFINITION_LOGIN);
if (response == null || response.isFailed()) {
connector.setupAuthenticator(null, null);
} else {
connector.setupAuthenticator(request.getUsername(), request.getPassword());
}
And here is the Authenticator
class Authenticator implements ClientRequestFilter {
#Override
public void filter(ClientRequestContext requestContext) throws IOException {
final MultivaluedMap<String, Object> headers = requestContext.getHeaders();
final String basicAuthentication = getBasicAuthentication();
if (basicAuthentication == null) return;
headers.add("Authorization", basicAuthentication);
}
void setup(String username, String password) {
this.user = username;
this.password = password;
}
private String getBasicAuthentication() {
if (user == null || password == null) return null;
final String token = this.user + ":" + this.password;
try {
return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
} catch (final UnsupportedEncodingException ex) {
throw new IllegalStateException("Cannot encode with UTF-8", ex);
}
}
private String password;
private String user;
}
on the server side i have an Authenticator
public class UserAuthenticator implements Authenticator<BasicCredentials, User> {
UserAuthenticator(UserDAO userDAO) {
this.userDAO = userDAO;
}
#UnitOfWork
#Override
public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
final String username = credentials.getUsername();
final Optional<DbUser> result = userDAO.getByName(username);
if (!result.isPresent()) return Optional.empty();
final DbUser user = result.get();
final String password = credentials.getPassword();
if (!StringUtils.equals(password, user.getPassword())) return Optional.empty();
if (!user.isOnline()) return Optional.empty();
user.handleAction();
userDAO.save(user);
return Optional.of(UserMgr.convert(user));
}
private final UserDAO userDAO;
}
And to get em working correctly:
SessionDao dao = new SessionDao(hibernateBundle.getSessionFactory());
ExampleAuthenticator exampleAuthenticator = new UnitOfWorkAwareProxyFactory(hibernateBundle)
.create(ExampleAuthenticator.class, SessionDao.class, dao);
So finally there is one REST-Call to login the User and the authentication is done on the result by the client automatically.

Table Not found - SQLITE error

I'm developing windows phone 8 application.
I'm having some difficulty with my sqlite prepare statement. I get an error saying my table does not exist, although I've checked in multiple places for it, and it does exist.
It did work until I added some new tables to the SQLite database and now it just doesn't recognise any of the tables - so I'm confused!
I have also tried hardcoding the full path.. e.g. C:\App\datbase.db etc
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.IO.IsolatedStorage;
using SQLitePCL;
namespace WP7.VideoScanZXing.SampleApp
{
public partial class Page1 : PhoneApplicationPage
{
string connLOCDAT = "Data Source =\\Resources\\DB\\MCRS_Data.sdf;Persist Security Info=False";
string connLOCLUDAT = "Data Source =\\Resources\\DB\\MCRSLU_MYCUBE.sdf;Persist Security Info=False";
public Page1()
{
InitializeComponent();
//check the isolated storage to see if the user has saved a username and password.
CheckIsoStore();
}
public void CheckIsoStore() {
if (IsolatedStorageSettings.ApplicationSettings.Contains("UsrEmail"))
{
//The user has saved details
//populate the email and password box automatically
//Dont forget to check the save details box too
tbEmail.Text = IsolatedStorageSettings.ApplicationSettings["UsrEmail"].ToString();
pbPassword.Password = IsolatedStorageSettings.ApplicationSettings["UsrPassword"].ToString();
cbSaveDetails.IsChecked = true;
}
}
public void failedLogin()
{
MessageBox.Show("Error: Email or Password are incorrect. Please try again.");
tbEmail.Focus();
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
//validate user
string strEmail = tbEmail.Text;
string strPassword = pbPassword.Password.ToString();
//bool bolValidUser = false;
//validate username and password here!
if (bolValidUser(strEmail, strPassword) == true)
{
//user has been validated and can continue.
if (cbSaveDetails.IsChecked == true)
{
//save the users details here
IsolatedStorageSettings.ApplicationSettings["UsrEmail"] = strEmail;
IsolatedStorageSettings.ApplicationSettings["UsrPassword"] = strPassword;
IsolatedStorageSettings.ApplicationSettings.Save();
}
else {
IsolatedStorageSettings.ApplicationSettings.Remove("UsrEmail");
IsolatedStorageSettings.ApplicationSettings.Remove("UsrPassword");
IsolatedStorageSettings.ApplicationSettings.Save();
}
NavigationService.Navigate(new Uri("/MenuPage.xaml", UriKind.Relative));
}
else {
//redirect the user back to the home screen with a message
//NavigationService.Navigate(new Uri("/LoginPage.xaml?message=Login error ", UriKind.Relative));
failedLogin();
}
}
public static SQLiteConnection dbConn;
public bool bolValidUser(string Uname, string PWord)
{
dbConn = new SQLitePCL.SQLiteConnection(Windows.ApplicationModel.Package.Current.InstalledLocation.Path + #"\bizData.db", SQLiteOpen.READWRITE);
{
//StorageFile databaseFile = await .GetFileAsync("bizData.db");
//await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);
}
//using (var statement = dbConn.Prepare(#"SELECT * FROM [MCRS_LU_Login] WHERE [Email] = " + Uname + " AND [Password] = " + PWord))
using (var statement = dbConn.Prepare(#"SELECT * FROM [BARCODES]"))
{
if (statement.Step() == SQLiteResult.ROW)
{
//new MessageDialog(Convert.ToString(statement.DataCount)).ShowAsync();
//if ()
string strLinkedUser;
strLinkedUser = statement[3].ToString();
IsolatedStorageSettings.ApplicationSettings["UsrADName"] = statement[0].ToString();
return true;
}
else
{
return false;
//await msgDialog.ShowAsync();
}
}
}
private void tbEmail_GotFocus(object sender, RoutedEventArgs e)
{
imgMail.Visibility = Visibility.Collapsed;
}
private void tbEmail_LostFocus(object sender, RoutedEventArgs e)
{
if(tbEmail.Text =="") {
imgMail.Visibility = Visibility.Visible;
}
}
private void pbPassword_LostFocus(object sender, RoutedEventArgs e)
{
if (pbPassword.Password == "")
{
imgPassword.Visibility = Visibility.Visible;
}
}
private void pbPassword_GotFocus(object sender, RoutedEventArgs e)
{
imgPassword.Visibility = Visibility.Collapsed;
}
}
}

how to make custom error feedback messages in SignInPanel in Wicket

I am implementing a LoginPage with Wicket, and I am not getting it, how to write the custom Feedback messages, for ex, "Password is wrong", "Username is wrong" or "Accound is locked out" (the last example should be a bit more difficult because it is related to Ldap/Ldap error messages I think.. But I think there is an easier way for the second two, with the properties file of my LoginPage or something like that.. I tried to change the default Wicket "login failed" message, and this through the properties' file of my page, I just added "signFailed=Sign in failed TEST", and it got changed.. but didn't got it how to tell the user why! Pass or username is wrong!
here the implementation:
public class LoginPage extends SampleManagementPage {
private static final long serialVersionUID = -8585718500226951823L;
private SignInPanel signIn;
public LoginPage() {
signIn = new SignInPanel("signInPanel");
add(signIn);
}
}
and my SampleManagementPage extends WebPage!
here the properties' file of LoginPage:
page.title=Login for Sample Management
signInFailed=Sign in failed TEST
The reason why you are able to change only the signFailed error message, is that wicket SignInPanel throws only this particular error in case it's sign-in form fails to authenticate. To see that, you can open the source code of SignInPanel.java.
One way to overcome the problem and produce your own error messages, is write your own sign-in panel. I m not saying it is the only way but it worked for me :)
public class LoginPanel extends Panel {
private static final long serialVersionUID = -1662154893824849377L;
private static final String SIGN_IN_FORM = "signInForm";
private boolean includeRememberMe = true;
private boolean rememberMe = true;
private String password;
private String username;
public LoginPanel(final String id, final boolean includeRememberMe) {
super(id);
this.includeRememberMe = includeRememberMe;
add(new FeedbackPanel("feedback"));
add(new SignInForm(SIGN_IN_FORM));
}
#Override
protected void onConfigure() {
if (isSignedIn() == false) {
IAuthenticationStrategy authenticationStrategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
String[] data = authenticationStrategy.load();
if ((data != null) && (data.length > 1)) {
if (signIn(data[0], data[1])) {
username = data[0];
password = data[1];
onSignInRemembered();
} else {
authenticationStrategy.remove();
}
}
}
super.onConfigure();
}
private boolean signIn(String username, String password) {
return AuthenticatedWebSession.get().signIn(username, password);
}
private boolean userExists(String username) {
return ((MyWebSession) AuthenticatedWebSession.get()).userExists(username);
}
private boolean isSignedIn() {
return AuthenticatedWebSession.get().isSignedIn();
}
protected void onSignInFailed() {
error(getLocalizer().getString("signInFailed", this, "Wrong password"));
}
private void onUserExistsFailed() {
error(getLocalizer().getString("userExistsFailed", this, "User does not exist"));
}
protected void onSignInSucceeded() {
continueToOriginalDestination();
setResponsePage(getApplication().getHomePage());
}
protected void onSignInRemembered() {
continueToOriginalDestination();
throw new RestartResponseException(getApplication().getHomePage());
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public LoginPanel(final String id) {
this(id, true);
}
public final class SignInForm extends StatelessForm<LoginPanel> {
private static final long serialVersionUID = 1L;
public SignInForm(final String id) {
super(id);
setModel(new CompoundPropertyModel<LoginPanel>(LoginPanel.this));
add(new TextField<String>("username"));
add(new PasswordTextField("password"));
WebMarkupContainer rememberMeRow = new WebMarkupContainer("rememberMeRow");
add(rememberMeRow);
rememberMeRow.add(new CheckBox("rememberMe"));
rememberMeRow.setVisible(includeRememberMe);
}
#Override
public final void onSubmit() {
IAuthenticationStrategy strategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
if (!userExists(username)) {
onUserExistsFailed();
strategy.remove();
return;
}
if (signIn(getUsername(), getPassword())) {
if (rememberMe == true) {
strategy.save(username, password);
} else {
strategy.remove();
}
onSignInSucceeded();
} else {
onSignInFailed();
strategy.remove();
}
}
}
}
public class MyWebSession extends AuthenticatedWebSession {
private static final long serialVersionUID = -401924496527311251L;
public MyWebSession(Request request) {
super(request);
}
public boolean userExists(String username) {
// business login
}
#Override
public boolean authenticate(String username, String password) {
// business login
}
#Override
public Roles getRoles() {
Roles roles = new Roles();
roles.add(Roles.USER);
return roles;
}
}

REST Web Service using Java and Jersey API: Unable to Read data from DB

I am creating a REST Web Service using Java and Jersey API. The basic REST service works fine,but when I add in a DB connection it gives me a Class Not Found Exception and a SQL Exception - No driver found. I have included the ojdbc6.jar file in the Eclipse build path. Using the same code if I create a Java application it runs fine.
I have added my code below. Can some one plz suggest something.
EDIT: I included the jar file in the WEB-INF lib directory. But when I try to execute the code I get the following error: HTTP Status 405 - Method Not Allowed
public class Note {
private int noteId;
private String content;
private Date createdDate;
public Note() {}
public Note(int noteId, String content, Date createdDate) {
this.noteId = noteId;
this.content = content;
this.createdDate = createdDate;
}
public int getNoteId() {
return noteId;
}
public void setNoteId(int noteId) {
this.noteId = noteId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
#Override
public String toString() {
return "Note [content=" + content + ", createdDate=" + createdDate
+ ", noteId=" + noteId + "]";
}
}
public class NoteDAO {
DatabaseAccess data;
Connection connection;
public NoteDAO()
{
try {
data = new DatabaseAccess();
connect();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void connect() throws SQLException
{
try
{
data.connect();
connection = data.connection;
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public Note getNoteById(int id)
{
PreparedStatement prepStmt = null;
try {
String cSQL = "SELECT * FROM NOTE WHERE NOTEID = 12 ";
prepStmt = connection.prepareStatement(cSQL);
prepStmt.setInt(1, id);
ResultSet result = prepStmt.executeQuery();
Note note = new Note();
while (result.next())
{
note.setNoteId(result.getInt(1));
note.setContent(result.getString(2));
note.setCreatedDate( (Date) new java.util.Date(result.getDate(3).getTime()));
}
return note;
} catch (SQLException e) {
e.printStackTrace();
prepStmt = null;
return null;
}
}
}
#Path("/notes")
public class Notes {
#Context
UriInfo uriInfo;
#Context
Request request;
NoteDAO dao = new NoteDAO();
#Path("{note}")
#GET
#Produces(MediaType.APPLICATION_XML)
public Note getNote(
#PathParam("note") String idStr) {
int id = Integer.parseInt(idStr);
Note note = dao.getNoteById(id);
if(note==null)
throw new RuntimeException("Get: Note with " + id + " not found");
return note;
}
public class DatabaseAccess {
Connection connection = null;
public void connect() throws SQLException
{
String DRIVER = "oracle.jdbc.driver.OracleDriver";
String URL = "jdbc:oracle:thin:#xx.xxx.xx.xxx:1521:XXXX";
String UserName = "username";
String Password = "password";
try
{
Class.forName(DRIVER);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
try
{
connection = DriverManager.getConnection(URL,UserName,Password);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void disconnect() throws SQLException
{
connection.close();
}
}
If you are using datasources that are managed by the application server, you need to put the ojdbc6.jar library inside the lib folder of your application server.
On JBoss for example, it would be $JBOSS_HOME/server/default/lib.
This is required, because in such case, the datasource is being build when the server starts and independently from your application, which means the server cannot use your application JARs.
If, however, you are pooling the connections yourself, you need to make sure, that the ojdbc6.jar is inside the lib folder of your application WAR archive.