Merge pull request #1442 from menocar/password

Add a password user authentication when connecting to servers.
This commit is contained in:
LevelX2 2016-01-06 23:31:25 +01:00
commit aadc253afa
12 changed files with 258 additions and 24 deletions

View file

@ -40,6 +40,7 @@
<Component id="lblPort" alignment="1" min="-2" max="-2" attributes="0"/> <Component id="lblPort" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="lblServer" min="-2" max="-2" attributes="0"/> <Component id="lblServer" min="-2" max="-2" attributes="0"/>
<Component id="lblUserName" min="-2" max="-2" attributes="0"/> <Component id="lblUserName" min="-2" max="-2" attributes="0"/>
<Component id="lblPassword" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Component id="lblFlag" alignment="1" min="-2" max="-2" attributes="0"/> <Component id="lblFlag" alignment="1" min="-2" max="-2" attributes="0"/>
</Group> </Group>
@ -53,6 +54,7 @@
<Component id="txtServer" pref="286" max="32767" attributes="0"/> <Component id="txtServer" pref="286" max="32767" attributes="0"/>
<Component id="txtPort" alignment="0" min="-2" pref="71" max="-2" attributes="0"/> <Component id="txtPort" alignment="0" min="-2" pref="71" max="-2" attributes="0"/>
<Component id="txtUserName" alignment="1" max="32767" attributes="0"/> <Component id="txtUserName" alignment="1" max="32767" attributes="0"/>
<Component id="txtPassword" alignment="1" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="btnFind" min="-2" max="-2" attributes="0"/> <Component id="btnFind" min="-2" max="-2" attributes="0"/>
@ -85,6 +87,11 @@
<Component id="txtUserName" min="-2" max="-2" attributes="0"/> <Component id="txtUserName" min="-2" max="-2" attributes="0"/>
<Component id="lblUserName" min="-2" max="-2" attributes="0"/> <Component id="lblUserName" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtPassword" min="-2" max="-2" attributes="0"/>
<Component id="lblPassword" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lblFlag" max="32767" attributes="0"/> <Component id="lblFlag" max="32767" attributes="0"/>
@ -152,6 +159,16 @@
</Component> </Component>
<Component class="javax.swing.JTextField" name="txtUserName"> <Component class="javax.swing.JTextField" name="txtUserName">
</Component> </Component>
<Component class="javax.swing.JLabel" name="lblPassword">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtPassword"/>
</Property>
<Property name="text" type="java.lang.String" value="Password:"/>
</Properties>
</Component>
<Component class="javax.swing.JPasswordField" name="txtPassword">
</Component>
<Component class="javax.swing.JLabel" name="lblFlag"> <Component class="javax.swing.JLabel" name="lblFlag">
<Properties> <Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">

View file

@ -90,15 +90,17 @@ public class ConnectDialog extends MageDialog {
public ConnectDialog() { public ConnectDialog() {
initComponents(); initComponents();
this.txtUserName.addActionListener(connectAction);
this.txtServer.addActionListener(connectAction); this.txtServer.addActionListener(connectAction);
this.txtPort.addActionListener(connectAction); this.txtPort.addActionListener(connectAction);
this.txtUserName.addActionListener(connectAction);
this.txtPassword.addActionListener(connectAction);
} }
public void showDialog() { public void showDialog() {
this.txtServer.setText(MageFrame.getPreferences().get("serverAddress", Config.serverName)); this.txtServer.setText(MageFrame.getPreferences().get("serverAddress", Config.serverName));
this.txtPort.setText(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port))); this.txtPort.setText(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port)));
this.txtUserName.setText(MageFrame.getPreferences().get("userName", "")); this.txtUserName.setText(MageFrame.getPreferences().get("userName", ""));
this.txtPassword.setText(MageFrame.getPreferences().get("password", ""));
this.chkAutoConnect.setSelected(Boolean.parseBoolean(MageFrame.getPreferences().get(KEY_CONNECT_AUTO_CONNECT, "false"))); this.chkAutoConnect.setSelected(Boolean.parseBoolean(MageFrame.getPreferences().get(KEY_CONNECT_AUTO_CONNECT, "false")));
this.chkForceUpdateDB.setSelected(false); // has always to be set manually to force comparison this.chkForceUpdateDB.setSelected(false); // has always to be set manually to force comparison
@ -120,6 +122,7 @@ public class ConnectDialog extends MageDialog {
MageFrame.getPreferences().put("serverAddress", txtServer.getText().trim()); MageFrame.getPreferences().put("serverAddress", txtServer.getText().trim());
MageFrame.getPreferences().put("serverPort", txtPort.getText().trim()); MageFrame.getPreferences().put("serverPort", txtPort.getText().trim());
MageFrame.getPreferences().put("userName", txtUserName.getText().trim()); MageFrame.getPreferences().put("userName", txtUserName.getText().trim());
MageFrame.getPreferences().put("password", txtPassword.getText().trim());
MageFrame.getPreferences().put(KEY_CONNECT_AUTO_CONNECT, Boolean.toString(chkAutoConnect.isSelected())); MageFrame.getPreferences().put(KEY_CONNECT_AUTO_CONNECT, Boolean.toString(chkAutoConnect.isSelected()));
} }
@ -139,6 +142,8 @@ public class ConnectDialog extends MageDialog {
txtPort = new javax.swing.JTextField(); txtPort = new javax.swing.JTextField();
lblUserName = new javax.swing.JLabel(); lblUserName = new javax.swing.JLabel();
txtUserName = new javax.swing.JTextField(); txtUserName = new javax.swing.JTextField();
lblPassword = new javax.swing.JLabel();
txtPassword = new javax.swing.JPasswordField();
lblFlag = new javax.swing.JLabel(); lblFlag = new javax.swing.JLabel();
cbFlag = new mage.client.util.gui.countryBox.CountryComboBox(); cbFlag = new mage.client.util.gui.countryBox.CountryComboBox();
chkAutoConnect = new javax.swing.JCheckBox(); chkAutoConnect = new javax.swing.JCheckBox();
@ -175,6 +180,21 @@ public class ConnectDialog extends MageDialog {
lblUserName.setLabelFor(txtUserName); lblUserName.setLabelFor(txtUserName);
lblUserName.setText("User name:"); lblUserName.setText("User name:");
txtUserName.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtUserNameActionPerformed(evt);
}
});
lblPassword.setLabelFor(txtPassword);
lblPassword.setText("Password:");
txtPassword.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtPasswordActionPerformed(evt);
}
});
lblFlag.setLabelFor(txtUserName); lblFlag.setLabelFor(txtUserName);
lblFlag.setText("User flag:"); lblFlag.setText("User flag:");
@ -234,7 +254,8 @@ public class ConnectDialog extends MageDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lblPort) .addComponent(lblPort)
.addComponent(lblServer) .addComponent(lblServer)
.addComponent(lblUserName)) .addComponent(lblUserName)
.addComponent(lblPassword))
.addComponent(lblFlag, javax.swing.GroupLayout.Alignment.TRAILING)) .addComponent(lblFlag, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -245,7 +266,8 @@ public class ConnectDialog extends MageDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(txtServer, javax.swing.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE) .addComponent(txtServer, javax.swing.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
.addComponent(txtPort, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(txtPort, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(txtUserName)) .addComponent(txtUserName)
.addComponent(txtPassword))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFind)) .addComponent(btnFind))
.addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
@ -269,6 +291,10 @@ public class ConnectDialog extends MageDialog {
.addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblUserName)) .addComponent(lblUserName))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblPassword))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lblFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lblFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(cbFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(cbFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
@ -302,10 +328,6 @@ public class ConnectDialog extends MageDialog {
private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed
if (txtUserName.getText().isEmpty()) {
JOptionPane.showMessageDialog(rootPane, "Please provide a user name");
return;
}
if (txtServer.getText().trim().isEmpty()) { if (txtServer.getText().trim().isEmpty()) {
JOptionPane.showMessageDialog(rootPane, "Please provide a server address"); JOptionPane.showMessageDialog(rootPane, "Please provide a server address");
return; return;
@ -314,6 +336,14 @@ public class ConnectDialog extends MageDialog {
JOptionPane.showMessageDialog(rootPane, "Please provide a port number"); JOptionPane.showMessageDialog(rootPane, "Please provide a port number");
return; return;
} }
if (txtUserName.getText().isEmpty()) {
JOptionPane.showMessageDialog(rootPane, "Please provide a user name");
return;
}
if (txtPassword.getText().isEmpty()) {
JOptionPane.showMessageDialog(rootPane, "Please provide a password");
return;
}
if (Integer.valueOf(txtPort.getText()) < 1 || Integer.valueOf(txtPort.getText()) > 65535) { if (Integer.valueOf(txtPort.getText()) < 1 || Integer.valueOf(txtPort.getText()) > 65535) {
JOptionPane.showMessageDialog(rootPane, "Invalid port number"); JOptionPane.showMessageDialog(rootPane, "Invalid port number");
txtPort.setText(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port))); txtPort.setText(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port)));
@ -327,6 +357,7 @@ public class ConnectDialog extends MageDialog {
connection.setHost(this.txtServer.getText().trim()); connection.setHost(this.txtServer.getText().trim());
connection.setPort(Integer.valueOf(this.txtPort.getText().trim())); connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
connection.setUsername(this.txtUserName.getText().trim()); connection.setUsername(this.txtUserName.getText().trim());
connection.setPassword(this.txtPassword.getText().trim());
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected()); connection.setForceDBComparison(this.chkForceUpdateDB.isSelected());
MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor) cbFlag.getEditor()).getImageItem()); MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor) cbFlag.getEditor()).getImageItem());
@ -541,6 +572,14 @@ public class ConnectDialog extends MageDialog {
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_chkForceUpdateDBActionPerformed }//GEN-LAST:event_chkForceUpdateDBActionPerformed
private void txtUserNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtUserNameActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_txtUserNameActionPerformed
private void txtPasswordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtPasswordActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_txtPasswordActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel; private javax.swing.JButton btnCancel;
private javax.swing.JButton btnConnect; private javax.swing.JButton btnConnect;
@ -550,10 +589,12 @@ public class ConnectDialog extends MageDialog {
private javax.swing.JCheckBox chkForceUpdateDB; private javax.swing.JCheckBox chkForceUpdateDB;
private javax.swing.JButton jProxySettingsButton; private javax.swing.JButton jProxySettingsButton;
private javax.swing.JLabel lblFlag; private javax.swing.JLabel lblFlag;
private javax.swing.JLabel lblPassword;
private javax.swing.JLabel lblPort; private javax.swing.JLabel lblPort;
private javax.swing.JLabel lblServer; private javax.swing.JLabel lblServer;
private javax.swing.JLabel lblStatus; private javax.swing.JLabel lblStatus;
private javax.swing.JLabel lblUserName; private javax.swing.JLabel lblUserName;
private javax.swing.JPasswordField txtPassword;
private javax.swing.JTextField txtPort; private javax.swing.JTextField txtPort;
private javax.swing.JTextField txtServer; private javax.swing.JTextField txtServer;
private javax.swing.JTextField txtUserName; private javax.swing.JTextField txtUserName;

View file

@ -56,7 +56,7 @@ import mage.view.UserView;
public interface MageServer { public interface MageServer {
// connection methods // connection methods
boolean registerClient(String userName, String sessionId, MageVersion version) throws MageException; boolean registerClient(String userName, String password, String sessionId, MageVersion version) throws MageException;
boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException; boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException;
// Not used // Not used

View file

@ -45,6 +45,7 @@ public class Connection {
private int port; private int port;
private String username; private String username;
private String password; private String password;
private String adminPassword;
private ProxyType proxyType; private ProxyType proxyType;
private String proxyHost; private String proxyHost;
private int proxyPort; private int proxyPort;
@ -172,6 +173,14 @@ public class Connection {
this.password = password; this.password = password;
} }
public String getAdminPassword() {
return adminPassword;
}
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}
public String getProxyHost() { public String getProxyHost() {
return proxyHost; return proxyHost;
} }

View file

@ -278,14 +278,14 @@ public class SessionImpl implements Session {
this.sessionId = callbackClient.getSessionId(); this.sessionId = callbackClient.getSessionId();
boolean registerResult; boolean registerResult;
if (connection.getPassword() == null) { if (connection.getAdminPassword() == null) {
// for backward compatibility. don't remove twice call - first one does nothing but for version checking // for backward compatibility. don't remove twice call - first one does nothing but for version checking
registerResult = server.registerClient(connection.getUsername(), sessionId, client.getVersion()); registerResult = server.registerClient(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion());
if (registerResult) { if (registerResult) {
server.setUserData(connection.getUsername(), sessionId, connection.getUserData()); server.setUserData(connection.getUsername(), sessionId, connection.getUserData());
} }
} else { } else {
registerResult = server.registerAdmin(connection.getPassword(), sessionId, client.getVersion()); registerResult = server.registerAdmin(connection.getAdminPassword(), sessionId, client.getVersion());
} }
if (registerResult) { if (registerResult) {
sessionState = SessionState.CONNECTED; sessionState = SessionState.CONNECTED;

View file

@ -413,7 +413,7 @@ public class ConnectDialog extends JDialog {
connection = new Connection(); connection = new Connection();
connection.setHost(this.txtServer.getText()); connection.setHost(this.txtServer.getText());
connection.setPort(Integer.valueOf(this.txtPort.getText())); connection.setPort(Integer.valueOf(this.txtPort.getText()));
connection.setPassword(new String(txtPassword.getPassword())); connection.setAdminPassword(new String(txtPassword.getPassword()));
connection.setUsername("Admin"); connection.setUsername("Admin");
connection.setProxyType((ProxyType) this.cbProxyType.getSelectedItem()); connection.setProxyType((ProxyType) this.cbProxyType.getSelectedItem());
if (!this.cbProxyType.getSelectedItem().equals(ProxyType.NONE)) { if (!this.cbProxyType.getSelectedItem().equals(ProxyType.NONE)) {

View file

@ -148,6 +148,12 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.4</version>
<type>jar</type>
</dependency>
</dependencies> </dependencies>
<build> <build>

View file

@ -0,0 +1,52 @@
package mage.server;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.hash.Hash;
@DatabaseTable(tableName = "authorized_user")
public class AuthorizedUser {
@DatabaseField(indexName = "name_index")
protected String name;
@DatabaseField
protected String password;
@DatabaseField
protected String salt;
@DatabaseField
protected String hashAlgorithm;
@DatabaseField
protected int hashIterations;
public AuthorizedUser() {
}
public AuthorizedUser(String name, Hash hash) {
this.name = name;
this.password = hash.toBase64();
this.salt = hash.getSalt().toBase64();
this.hashAlgorithm = hash.getAlgorithmName();
this.hashIterations = hash.getIterations();
}
public boolean doCredentialsMatch(String name, String password) {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(this.hashAlgorithm);
matcher.setHashIterations(this.hashIterations);
AuthenticationToken token = new UsernamePasswordToken(name, password);
AuthenticationInfo info = new SimpleAuthenticationInfo(this.name,
ByteSource.Util.bytes(Base64.decode(this.password)),
ByteSource.Util.bytes(Base64.decode(this.salt)), "");
return matcher.doCredentialsMatch(token, info);
}
}

View file

@ -0,0 +1,97 @@
package mage.server;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.support.DatabaseConnection;
import com.j256.ormlite.table.TableUtils;
import java.io.File;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.Callable;
import mage.cards.repository.RepositoryUtil;
import org.apache.log4j.Logger;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Hash;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
public enum AuthorizedUserRepository {
instance;
private static final String JDBC_URL = "jdbc:h2:file:./db/authorized_user.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "authorized_user";
// raise this if db structure was changed
private static final long DB_VERSION = 0;
private static final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
private Dao<AuthorizedUser, Object> dao;
private AuthorizedUserRepository() {
File file = new File("db");
if (!file.exists()) {
file.mkdirs();
}
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
boolean obsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, DB_VERSION);
if (obsolete) {
TableUtils.dropTable(connectionSource, AuthorizedUser.class, true);
}
TableUtils.createTableIfNotExists(connectionSource, AuthorizedUser.class);
dao = DaoManager.createDao(connectionSource, AuthorizedUser.class);
} catch (SQLException ex) {
Logger.getLogger(AuthorizedUserRepository.class).error("Error creating authorized_user repository - ", ex);
}
}
public void add(final String userName, final String password) {
try {
dao.callBatchTasks(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
Hash hash = new SimpleHash(Sha256Hash.ALGORITHM_NAME, password, rng.nextBytes(), 1024);
AuthorizedUser user = new AuthorizedUser(userName, hash);
dao.create(user);
} catch (SQLException ex) {
Logger.getLogger(AuthorizedUserRepository.class).error("Error adding a user to DB - ", ex);
}
return null;
}
});
} catch (Exception ex) {
}
}
public AuthorizedUser get(String userName) {
try {
QueryBuilder<AuthorizedUser, Object> qb = dao.queryBuilder();
qb.where().eq("name", new SelectArg(userName));
List<AuthorizedUser> results = dao.query(qb.prepare());
if (results.size() == 1) {
return results.get(0);
}
return null;
} catch (SQLException ex) {
}
return null;
}
public void closeDB() {
try {
if (dao != null && dao.getConnectionSource() != null) {
DatabaseConnection conn = dao.getConnectionSource().getReadWriteConnection();
conn.executeStatement("shutdown compact", 0);
}
} catch (SQLException ex) {
}
}
}

View file

@ -96,24 +96,24 @@ public class MageServerImpl implements MageServer {
private static final Logger logger = Logger.getLogger(MageServerImpl.class); private static final Logger logger = Logger.getLogger(MageServerImpl.class);
private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
private final String password; private final String adminPassword;
private final boolean testMode; private final boolean testMode;
public MageServerImpl(String password, boolean testMode) { public MageServerImpl(String adminPassword, boolean testMode) {
this.password = password; this.adminPassword = adminPassword;
this.testMode = testMode; this.testMode = testMode;
ServerMessagesUtil.getInstance().getMessages(); ServerMessagesUtil.getInstance().getMessages();
} }
@Override @Override
public boolean registerClient(String userName, String sessionId, MageVersion version) throws MageException { public boolean registerClient(String userName, String password, String sessionId, MageVersion version) throws MageException {
try { try {
if (version.compareTo(Main.getVersion()) != 0) { if (version.compareTo(Main.getVersion()) != 0) {
logger.info("MageVersionException: userName=" + userName + ", version=" + version); logger.info("MageVersionException: userName=" + userName + ", version=" + version);
LogServiceImpl.instance.log(LogKeys.KEY_WRONG_VERSION, userName, version.toString(), Main.getVersion().toString(), sessionId); LogServiceImpl.instance.log(LogKeys.KEY_WRONG_VERSION, userName, version.toString(), Main.getVersion().toString(), sessionId);
throw new MageVersionException(version, Main.getVersion()); throw new MageVersionException(version, Main.getVersion());
} }
return SessionManager.getInstance().registerUser(sessionId, userName); return SessionManager.getInstance().registerUser(sessionId, userName, password);
} catch (MageException ex) { } catch (MageException ex) {
if (ex instanceof MageVersionException) { if (ex instanceof MageVersionException) {
throw (MageVersionException) ex; throw (MageVersionException) ex;
@ -134,12 +134,12 @@ public class MageServerImpl implements MageServer {
} }
@Override @Override
public boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException { public boolean registerAdmin(String adminPassword, String sessionId, MageVersion version) throws MageException {
try { try {
if (version.compareTo(Main.getVersion()) != 0) { if (version.compareTo(Main.getVersion()) != 0) {
throw new MageException("Wrong client version " + version + ", expecting version " + Main.getVersion()); throw new MageException("Wrong client version " + version + ", expecting version " + Main.getVersion());
} }
if (!password.equals(this.password)) { if (!adminPassword.equals(this.adminPassword)) {
throw new MageException("Wrong password"); throw new MageException("Wrong password");
} }
return SessionManager.getInstance().registerAdmin(sessionId); return SessionManager.getInstance().registerAdmin(sessionId);

View file

@ -74,8 +74,8 @@ public class Session {
this.lock = new ReentrantLock(); this.lock = new ReentrantLock();
} }
public String registerUser(String userName) throws MageException { public String registerUser(String userName, String password) throws MageException {
String returnMessage = registerUserHandling(userName); String returnMessage = registerUserHandling(userName, password);
if (returnMessage != null) { if (returnMessage != null) {
sendErrorMessageToClient(returnMessage); sendErrorMessageToClient(returnMessage);
} }
@ -86,7 +86,7 @@ public class Session {
return lock.isLocked(); return lock.isLocked();
} }
public String registerUserHandling(String userName) throws MageException { public String registerUserHandling(String userName, String password) throws MageException {
this.isAdmin = false; this.isAdmin = false;
if (userName.equals("Admin")) { if (userName.equals("Admin")) {
return "User name Admin already in use"; return "User name Admin already in use";
@ -102,6 +102,18 @@ public class Session {
if (m.find()) { if (m.find()) {
return "User name '" + userName + "' includes not allowed characters: use a-z, A-Z and 0-9"; return "User name '" + userName + "' includes not allowed characters: use a-z, A-Z and 0-9";
} }
AuthorizedUser authorizedUser = AuthorizedUserRepository.instance.get(userName);
if (authorizedUser == null) {
// Do this in an explicit sign-up flow.
AuthorizedUserRepository.instance.add(userName, password);
} else {
if (!authorizedUser.doCredentialsMatch(userName, password)) {
return "Wrong username or password";
}
}
// TODO: Do an authentication with userName and password.
User user = UserManager.getInstance().createUser(userName, host); User user = UserManager.getInstance().createUser(userName, host);
boolean reconnect = false; boolean reconnect = false;
if (user == null) { // user already exists if (user == null) { // user already exists

View file

@ -70,10 +70,10 @@ public class SessionManager {
sessions.put(sessionId, session); sessions.put(sessionId, session);
} }
public boolean registerUser(String sessionId, String userName) throws MageException { public boolean registerUser(String sessionId, String userName, String password) throws MageException {
Session session = sessions.get(sessionId); Session session = sessions.get(sessionId);
if (session != null) { if (session != null) {
String returnMessage = session.registerUser(userName); String returnMessage = session.registerUser(userName, password);
if (returnMessage == null) { if (returnMessage == null) {
LogServiceImpl.instance.log(LogKeys.KEY_USER_CONNECTED, userName, session.getHost(), sessionId); LogServiceImpl.instance.log(LogKeys.KEY_USER_CONNECTED, userName, session.getHost(), sessionId);