Unverified 提交 6c004246 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1211 from katzyn/misc

Assorted minor changes
......@@ -21,19 +21,19 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1177: Resource leak in Recover tool
<li>Issue #1177: Resource leak in Recover tool
</li>
<li>PR #1183: Improve concurrency of connection pool with wait-free implement
<li>PR #1183: Improve concurrency of connection pool with wait-free implement
</li>
<li>Issue #1073: H2 v1.4.197 fails to open an existing database with the error [Unique index or primary key violation: "PRIMARY KEY ON """".PAGE_INDEX"]
</li>
<li>PR #1179: Drop TransactionMap.readLogId
<li>PR #1179: Drop TransactionMap.readLogId
</li>
<li>PR #1181: Improve CURRENT_TIMESTAMP and add LOCALTIME and LOCALTIMESTAMP
</li>
<li>PR #1176: Magic value replacement with constant
</li>
<li>PR #1171: Introduce last commited value into a VersionedValue
<li>PR #1171: Introduce last committed value into a VersionedValue
</li>
<li>PR #1175: tighten test conditions - do not ignore any exceptions
</li>
......@@ -79,7 +79,7 @@ Change Log
</li>
<li>PR #1142: Misc small fixes
</li>
<li>PR #1141: Assorted optimizations and fixes
<li>PR #1141: Assorted optimizations and fixes
</li>
<li>PR #1138, #1139: Fix a memory leak caused by DatabaseCloser objects
</li>
......
......@@ -1835,7 +1835,7 @@ Is also possible to temporary assign roles to to externally authenticated users.
</p>
<p>Master user cannot be externally authenticated</p>
<p>
To enable external authentication on a database execute statement <code>SET AUTHENTICATOR TRUE</code>. This setting in persisted on the database.
To enable external authentication on a database execute statement <code>SET AUTHENTICATOR TRUE</code>. This setting in persisted on the database.
</p>
<p>
To connect on a database by using external credentials client must append <code>AUTHREALM=H2</code> to the database URL. <code>H2</code>
......@@ -1850,9 +1850,9 @@ JAAS login configuration file</a> content:
</p>
<pre>
h2 {
com.sun.security.auth.module.LdapLoginModule REQUIRED \
userProvider="ldap://127.0.0.1:10389" authIdentity="uid={USERNAME},ou=people,dc=example,dc=com" \
debug=true useSSL=false ;
com.sun.security.auth.module.LdapLoginModule REQUIRED \
userProvider="ldap://127.0.0.1:10389" authIdentity="uid={USERNAME},ou=people,dc=example,dc=com" \
debug=true useSSL=false ;
};
</pre>
<p>
......@@ -1863,14 +1863,14 @@ JVM argument <code>-Dh2auth.configurationFile={urlOfH2Auth.xml}</code>. Here an
&lt;h2Auth allowUserRegistration="false" createMissingRoles="true"&gt;
&lt;!-- realm: DUMMY authenticate users named DUMMY[0-9] with a static password --&gt;
&lt;realm name="DUMMY"
&lt;realm name="DUMMY"
validatorClass="org.h2.security.auth.impl.FixedPasswordCredentialsValidator"&gt;
&lt;property name="userNamePattern" value="DUMMY[0-9]" /&gt;
&lt;property name="userNamePattern" value="DUMMY[0-9]" /&gt;
&lt;property name="password" value="mock" /&gt;
&lt;/realm&gt;
&lt;!-- realm LDAPEXAMPLE:perform credentials validation on LDAP --&gt;
&lt;realm name="LDAPEXAMPLE"
&lt;realm name="LDAPEXAMPLE"
validatorClass="org.h2.security.auth.impl.LdapCredentialsValidator"&gt;
&lt;property name="bindDnPattern" value="uid=%u,ou=people,dc=example,dc=com" /&gt;
&lt;property name="host" value="127.0.0.1" /&gt;
......@@ -1879,7 +1879,7 @@ JVM argument <code>-Dh2auth.configurationFile={urlOfH2Auth.xml}</code>. Here an
&lt;/realm&gt;
&lt;!-- realm JAAS: perform credentials validation by using JAAS api --&gt;
&lt;realm name="JAAS"
&lt;realm name="JAAS"
validatorClass="org.h2.security.auth.impl.JaasCredentialsValidator"&gt;
&lt;property name="appName" value="H2" /&gt;
&lt;/realm&gt;
......
......@@ -174,6 +174,7 @@
90141=Serializer cannot be changed because there is a data table: {0}
90142=Step size must not be zero
90143=Row {1} not found in primary index {0}
90144=Authenticator not enabled on database {0}
HY000=General error: {0}
HY004=Unknown data type: {0}
HYC00=Feature not supported: {0}
......
......@@ -9,19 +9,23 @@ import org.h2.security.auth.AuthenticationInfo;
import org.h2.security.auth.Configurable;
/**
* A class that implement this interface can be used to validate
* credentials provided by client.
* A class that implement this interface can be used to validate credentials
* provided by client.
* <p>
* <b>This feature is experimental and subject to change</b>
* <b>This feature is experimental and subject to change</b>
* </p>
*/
public interface CredentialsValidator extends Configurable {
/**
* Validate user credential
* @param authenticationInfo = authentication info
* Validate user credential.
*
* @param authenticationInfo
* = authentication info
* @return true if credentials are valid, otherwise false
* @throws Exception any exception occurred (invalid credentials or internal issue) prevent user login
* @throws Exception
* any exception occurred (invalid credentials or internal
* issue) prevent user login
*/
boolean validateCredentials(AuthenticationInfo authenticationInfo) throws Exception;
......
......@@ -1993,15 +1993,15 @@ public class ErrorCode {
* The error with code <code>90144</code> is thrown when
* user trying to login into a database with AUTHREALM set and
* the target database doesn't have an authenticator defined
* <p>Authenticator experimental feature can be enabled by
* </p>
* <p>Authenticator experimental feature can be enabled by
* </p>
* <pre>
* SET AUTHENTICATOR TRUE
* </pre>
*/
public static final int AUTHENTICATOR_NOT_AVAILABLE = 90144;
// next are 90122, 90145
private ErrorCode() {
......
......@@ -6,26 +6,28 @@
package org.h2.api;
import java.util.Collection;
import java.util.Set;
import org.h2.security.auth.AuthenticationException;
import org.h2.security.auth.AuthenticationInfo;
import org.h2.security.auth.Configurable;
/**
* A class that implement this interface can be used during
* authentication to map external users to database roles.
* A class that implement this interface can be used during authentication to
* map external users to database roles.
* <p>
* <b>This feature is experimental and subject to change</b>
* <b>This feature is experimental and subject to change</b>
* </p>
*/
public interface UserToRolesMapper extends Configurable {
/**
* Map user identified by authentication info to a set of granted roles
* Map user identified by authentication info to a set of granted roles.
*
* @param authenticationInfo
* authentication information
* @return list of roles to be assigned to the user temporary
* @throws AuthenticationException
* on authentication exception
*/
Collection<String> mapUserToRoles(AuthenticationInfo authenticationInfo) throws AuthenticationException;
}
......@@ -321,7 +321,7 @@ public abstract class Command implements CommandInterface {
if (start != 0 && TimeUnit.NANOSECONDS.toMillis(now - start) > session.getLockTimeout()) {
throw DbException.get(ErrorCode.LOCK_TIMEOUT_1, e);
}
// Only in PageStore mode we need to sleep here to avoid buzy wait loop
// Only in PageStore mode we need to sleep here to avoid busy wait loop
Database database = session.getDatabase();
if (database.getMvStore() == null) {
int sleep = 1 + MathUtils.randomInt(10);
......
......@@ -548,9 +548,10 @@ public class Set extends Prepared {
}
addOrUpdateSetting(name,expression.getValue(session).getString(),0);
} catch (Exception e) {
//Errors during start are ignored to allow to open the database
// Errors during start are ignored to allow to open the database
if (database.isStarting()) {
database.getTrace(Trace.DATABASE).error(e, "{0}: failed to set authenticator during database start ",expression.toString());
database.getTrace(Trace.DATABASE).error(e,
"{0}: failed to set authenticator during database start ", expression.toString());
} else {
throw DbException.convert(e);
}
......
......@@ -76,7 +76,7 @@ public class ConnectionInfo implements Cloneable {
setUserName(removeProperty("USER", ""));
name = url.substring(Constants.START_URL.length());
parseName();
convertPasswords();
convertPasswords();
String recoverTest = removeProperty("RECOVER_TEST", null);
if (recoverTest != null) {
FilePathRec.register();
......@@ -279,7 +279,7 @@ public class ConnectionInfo implements Cloneable {
prop.put("AUTHZPWD",password instanceof char[] ? new String((char[])password) : password);
}
}
private char[] removePassword() {
Object p = prop.remove("PASSWORD");
preservePasswordForAuthentication(p);
......@@ -664,6 +664,9 @@ public class ConnectionInfo implements Cloneable {
return url;
}
/**
* Clear authentication properties.
*/
public void cleanAuthenticationInfo() {
removeProperty("AUTHREALM", false);
removeProperty("AUTHZPWD", false);
......
......@@ -2983,13 +2983,13 @@ public class Database implements DataHandler {
/**
* Set current database authenticator
*
*
* @param authenticator = authenticator to set, null to revert to the Internal authenticator
*/
public void setAuthenticator(Authenticator authenticator) {
if (authenticator!=null) {
authenticator.init(this);
};
}
this.authenticator=authenticator;
}
}
......@@ -153,9 +153,9 @@ public abstract class RightOwner extends DbObjectBase {
grantedRoles = null;
}
}
/**
* Remove all the temporary rights granted on roles
* Remove all the temporary rights granted on roles
*/
public void revokeTemporaryRightsOnRoles() {
if (grantedRoles == null) {
......@@ -171,8 +171,8 @@ public abstract class RightOwner extends DbObjectBase {
revokeRole(currentRoleToRemove);
}
}
/**
* Get the 'grant schema' right of this object.
......
......@@ -560,11 +560,11 @@ public class SysProperties {
* (default: null).<br />
* authConfigFile define the URL of configuration file
* of {@link org.h2.security.auth.DefaultAuthenticator}
*
*
*/
public static final String AUTH_CONFIG_FILE =
public static final String AUTH_CONFIG_FILE =
Utils.getProperty("h2.authConfigFile", null);
private static final String H2_BASE_DIR = "h2.baseDir";
private SysProperties() {
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import org.h2.security.auth.AuthenticationInfo;
......@@ -6,16 +11,24 @@ import org.h2.util.MathUtils;
public class UserBuilder {
/**
* build the database user starting from authentication informations
* @param authenticationInfo = authentication info
* @param database = target database
* @param persistent = true if the user will be persisted in the database
* Build the database user starting from authentication informations.
*
* @param authenticationInfo
* authentication info
* @param database
* target database
* @param persistent
* true if the user will be persisted in the database
* @return user bean
*/
public static User buildUser(AuthenticationInfo authenticationInfo, Database database, boolean persistent) {
User user = new User(database, persistent ? database.allocateObjectId() : -1, authenticationInfo.getFullyQualifiedName(), false);
//In case of external authentication fill the password hash with random data
user.setUserPasswordHash( authenticationInfo.getRealm()==null ? authenticationInfo.getConnectionInfo().getUserPasswordHash(): MathUtils.secureRandomBytes(64));
User user = new User(database, persistent ? database.allocateObjectId() : -1,
authenticationInfo.getFullyQualifiedName(), false);
// In case of external authentication fill the password hash with random
// data
user.setUserPasswordHash(
authenticationInfo.getRealm() == null ? authenticationInfo.getConnectionInfo().getUserPasswordHash()
: MathUtils.secureRandomBytes(64));
user.setTemporary(!persistent);
return user;
}
......
......@@ -11,7 +11,6 @@ import org.h2.schema.Sequence;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueLong;
/**
......@@ -27,9 +26,9 @@ public class SequenceValue extends Expression {
@Override
public Value getValue(Session session) {
long value = sequence.getNext(session);
session.setLastIdentity(ValueLong.get(value));
return ValueLong.get(value);
ValueLong value = ValueLong.get(sequence.getNext(session));
session.setLastIdentity(value);
return value;
}
@Override
......@@ -59,12 +58,12 @@ public class SequenceValue extends Expression {
@Override
public long getPrecision() {
return ValueInt.PRECISION;
return ValueLong.PRECISION;
}
@Override
public int getDisplaySize() {
return ValueInt.DISPLAY_SIZE;
return ValueLong.DISPLAY_SIZE;
}
@Override
......
......@@ -40,11 +40,10 @@ import org.h2.command.CommandInterface;
import org.h2.engine.ConnectionInfo;
import org.h2.engine.Constants;
import org.h2.engine.Mode;
import org.h2.engine.Mode.ModeEnum;
import org.h2.engine.SessionInterface;
import org.h2.engine.SessionRemote;
import org.h2.engine.SysProperties;
import org.h2.engine.Mode.ModeEnum;
import org.h2.engine.Session;
import org.h2.message.DbException;
import org.h2.message.TraceObject;
import org.h2.result.ResultInterface;
......
......@@ -114,6 +114,7 @@ public class DatabaseInfo implements DatabaseInfoMBean {
return database.isMultiThreaded();
}
@Deprecated
@Override
public boolean isMvcc() {
return database.isMVStore();
......
......@@ -53,6 +53,7 @@ public interface DatabaseInfoMBean {
*
* @return true if MVCC is enabled, false otherwise
*/
@Deprecated
boolean isMvcc();
/**
......
......@@ -2568,7 +2568,7 @@ public class MVStore {
String oldName = getMapName(id);
if (oldName != null && !oldName.equals(newName)) {
String idHexStr = Integer.toHexString(id);
// we need to cope whith the case of previously unfinished rename
// we need to cope with the case of previously unfinished rename
String existingIdHexStr = meta.get("name." + newName);
DataUtils.checkArgument(
existingIdHexStr == null || existingIdHexStr.equals(idHexStr),
......
......@@ -119,7 +119,7 @@ public class MVTable extends TableBase {
*/
private final ArrayDeque<Session> waitingSessions = new ArrayDeque<>();
private final Trace traceLock;
private final AtomicInteger changesUnitlAnalyze;
private final AtomicInteger changesUntilAnalyze;
private int nextAnalyze;
private final boolean containsLargeObject;
private Column rowIdColumn;
......@@ -130,7 +130,7 @@ public class MVTable extends TableBase {
public MVTable(CreateTableData data, MVTableEngine.Store store) {
super(data);
nextAnalyze = database.getSettings().analyzeAuto;
changesUnitlAnalyze = nextAnalyze <= 0 ? null : new AtomicInteger(nextAnalyze);
changesUntilAnalyze = nextAnalyze <= 0 ? null : new AtomicInteger(nextAnalyze);
this.store = store;
this.transactionStore = store.getTransactionStore();
this.isHidden = data.isHidden;
......@@ -714,8 +714,8 @@ public class MVTable extends TableBase {
Index index = indexes.get(i);
index.truncate(session);
}
if (changesUnitlAnalyze != null) {
changesUnitlAnalyze.set(nextAnalyze);
if (changesUntilAnalyze != null) {
changesUntilAnalyze.set(nextAnalyze);
}
}
......@@ -745,12 +745,12 @@ public class MVTable extends TableBase {
}
private void analyzeIfRequired(Session session) {
if (changesUnitlAnalyze != null) {
if (changesUnitlAnalyze.decrementAndGet() == 0) {
if (changesUntilAnalyze != null) {
if (changesUntilAnalyze.decrementAndGet() == 0) {
if (nextAnalyze <= Integer.MAX_VALUE / 2) {
nextAnalyze *= 2;
}
changesUnitlAnalyze.set(nextAnalyze);
changesUntilAnalyze.set(nextAnalyze);
session.markTableForAnalyze(this);
}
}
......
......@@ -149,7 +149,7 @@ public class MVTableEngine implements TableEngine {
* @param builder the builder
* @param encrypted whether the store is encrypted
*/
private void open(Database db, MVStore.Builder builder, boolean encrypted) {
void open(Database db, MVStore.Builder builder, boolean encrypted) {
this.encrypted = encrypted;
try {
this.store = builder.open();
......
......@@ -28,7 +28,7 @@ final class CommitDecisionMaker extends MVMap.DecisionMaker<VersionedValue> {
assert decision == null;
if (existingValue == null ||
// map entry was treated as already committed, and then
// it has been removed by another transaction (commited and closed by now )
// it has been removed by another transaction (committed and closed by now)
existingValue.getOperationId() != undoKey) {
// this is not a final undo log entry for this key,
// or map entry was treated as already committed and then
......
......@@ -30,8 +30,8 @@ final class RollbackDecisionMaker extends MVMap.DecisionMaker<Object[]> {
@Override
public MVMap.Decision decide(Object[] existingValue, Object[] providedValue) {
assert decision == null;
// normaly existingValue will always be there except of db initialization
// where some undo log enty was captured on disk but actual map entry was not
// normally existingValue will always be there except of db initialization
// where some undo log entry was captured on disk but actual map entry was not
if (existingValue != null ) {
VersionedValue valueToRestore = (VersionedValue) existingValue[2];
long operationId;
......
......@@ -475,14 +475,19 @@ public class Transaction {
public boolean waitFor(Transaction toWaitFor) {
if (isDeadlocked(toWaitFor)) {
StringBuilder details = new StringBuilder(String.format("Transaction %d has been chosen as a deadlock victim. Details:%n", transactionId));
for(Transaction tx = toWaitFor, nextTx; (nextTx = tx.blockingTransaction) != null; tx = nextTx) {
details.append(String.format("Transaction %d attempts to update map <%s> entry with key <%s> modified by transaction %s%n",
StringBuilder details = new StringBuilder(
String.format("Transaction %d has been chosen as a deadlock victim. Details:%n", transactionId));
for (Transaction tx = toWaitFor, nextTx; (nextTx = tx.blockingTransaction) != null; tx = nextTx) {
details.append(String.format(
"Transaction %d attempts to update map <%s> entry with key <%s> modified by transaction %s%n",
tx.transactionId, tx.blockingMap.getName(), tx.blockingKey, tx.blockingTransaction));
if (nextTx == this) {
details.append(String.format("Transaction %d attempts to update map <%s> entry with key <%s> modified by transaction %s%n",
details.append(String.format(
"Transaction %d attempts to update map <%s> entry with key <%s>"
+ " modified by transaction %s%n",
transactionId, blockingMap.getName(), blockingKey, toWaitFor));
throw DataUtils.newIllegalStateException(DataUtils.ERROR_TRANSACTIONS_DEADLOCK, details.toString());
throw DataUtils.newIllegalStateException(DataUtils.ERROR_TRANSACTIONS_DEADLOCK,
details.toString());
}
}
}
......
......@@ -109,7 +109,7 @@ public class TransactionMap<K, V> {
// Entries describing removals from the map by this transaction and all transactions,
// which are committed but not closed yet,
// and antries about additions to the map by other uncommitted transactions were counted,
// and entries about additions to the map by other uncommitted transactions were counted,
// but they should not contribute into total count.
if (2 * undoLogSize > size) {
// the undo log is larger than half of the map - scan the entries of the map directly
......@@ -130,7 +130,8 @@ public class TransactionMap<K, V> {
}
}
} else {
// The undo logs are much smaller than the map - scan all undo logs, and then lookup relevant map entry.
// The undo logs are much smaller than the map - scan all undo logs,
// and then lookup relevant map entry.
for (MVMap.RootReference undoLogRootReference : undoLogRootReferences) {
if (undoLogRootReference != null) {
Cursor<Long, Object[]> cursor = new Cursor<>(undoLogRootReference.root, null);
......@@ -139,12 +140,15 @@ public class TransactionMap<K, V> {
Object op[] = cursor.getValue();
if ((int) op[0] == map.getId()) {
VersionedValue currentValue = map.get(mapRootPage, op[1]);
// If map entry is not there, then we never counted it, in the first place, so skip it.
// This is possible when undo entry exists because it belongs
// to a committed but not yet closed transaction,
// and it was later deleted by some other already committed and closed transaction.
// If map entry is not there, then we never counted
// it, in the first place, so skip it.
// This is possible when undo entry exists because
// it belongs to a committed but not yet closed
// transaction, and it was later deleted by some
// other already committed and closed transaction.
if (currentValue != null) {
// only the last undo entry for any given map key should be considered
// only the last undo entry for any given map
// key should be considered
long operationId = cursor.getKey();
if (currentValue.getOperationId() == operationId) {
int txId = TransactionStore.getTransactionId(operationId);
......@@ -204,7 +208,8 @@ public class TransactionMap<K, V> {
*/
public V putIfAbsent(K key, V value) {
DataUtils.checkArgument(value != null, "The value may not be null");
TxDecisionMaker decisionMaker = new TxDecisionMaker.PutIfAbsentDecisionMaker(map.getId(), key, value, transaction);
TxDecisionMaker decisionMaker = new TxDecisionMaker.PutIfAbsentDecisionMaker(map.getId(), key, value,
transaction);
return set(key, decisionMaker);
}
......@@ -275,8 +280,10 @@ public class TransactionMap<K, V> {
} while (blockingTransaction.sequenceNum > sequenceNumWhenStarted || transaction.waitFor(blockingTransaction));
throw DataUtils.newIllegalStateException(DataUtils.ERROR_TRANSACTION_LOCKED,
"Map entry <{0}> with key <{1}> and value {2} is locked by tx {3} and can not be updated by tx {4} within allocated time interval {5} ms.",
map.getName(), key, result, blockingTransaction.transactionId, transaction.transactionId, transaction.timeoutMillis);
"Map entry <{0}> with key <{1}> and value {2} is locked by tx {3} and can not be updated by tx {4}"
+ " within allocated time interval {5} ms.",
map.getName(), key, result, blockingTransaction.transactionId, transaction.transactionId,
transaction.timeoutMillis);
}
/**
......@@ -319,7 +326,8 @@ public class TransactionMap<K, V> {
*/
public boolean trySet(K key, V value) {
try {
// TODO: effective transaction.timeoutMillis should be set to 0 here and restored before return
// TODO: effective transaction.timeoutMillis should be set to 0 here
// and restored before return
// TODO: eliminate exception usage as part of normal control flaw
set(key, value);
return true;
......
......@@ -89,7 +89,7 @@ public class TransactionStore {
private final AtomicReferenceArray<Transaction> transactions =
new AtomicReferenceArray<>(MAX_OPEN_TRANSACTIONS + 1);
private static final String UNDO_LOG_NAME_PEFIX = "undoLog";
private static final String UNDO_LOG_NAME_PREFIX = "undoLog";
private static final char UNDO_LOG_COMMITTED = '-'; // must come before open in lexicographical order
private static final char UNDO_LOG_OPEN = '.';
......@@ -101,7 +101,7 @@ public class TransactionStore {
public static String getUndoLogName(boolean committed, int transactionId) {
return UNDO_LOG_NAME_PEFIX +
return UNDO_LOG_NAME_PREFIX +
(committed ? UNDO_LOG_COMMITTED : UNDO_LOG_OPEN) +
(transactionId > 0 ? String.valueOf(transactionId) : "");
}
......@@ -120,7 +120,7 @@ public class TransactionStore {
*
* @param store the store
* @param dataType the data type for map keys and values
* @param timeoutMillis lock aquisition timeout in milliseconds, 0 means no wait
* @param timeoutMillis lock acquisition timeout in milliseconds, 0 means no wait
*/
public TransactionStore(MVStore store, DataType dataType, int timeoutMillis) {
this.store = store;
......@@ -143,10 +143,10 @@ public class TransactionStore {
public void init() {
if (!init) {
for (String mapName : store.getMapNames()) {
if (mapName.startsWith(UNDO_LOG_NAME_PEFIX)) {
boolean committed = mapName.charAt(UNDO_LOG_NAME_PEFIX.length()) == UNDO_LOG_COMMITTED;
if (mapName.startsWith(UNDO_LOG_NAME_PREFIX)) {
boolean committed = mapName.charAt(UNDO_LOG_NAME_PREFIX.length()) == UNDO_LOG_COMMITTED;
if (store.hasData(mapName) || committed) {
int transactionId = Integer.parseInt(mapName.substring(UNDO_LOG_NAME_PEFIX.length() + 1));
int transactionId = Integer.parseInt(mapName.substring(UNDO_LOG_NAME_PREFIX.length() + 1));
VersionedBitSet openTxBitSet = openTransactions.get();
if (!openTxBitSet.get(transactionId)) {
Object[] data = preparedTransactions.get(transactionId);
......@@ -168,7 +168,8 @@ public class TransactionStore {
assert committed || lastUndoKey != null;
assert committed || getTransactionId(lastUndoKey) == transactionId;
long logId = lastUndoKey == null ? 0 : getLogId(lastUndoKey) + 1;
registerTransaction(transactionId, status, name, logId, timeoutMillis, 0, RollbackListener.NONE);
registerTransaction(transactionId, status, name, logId, timeoutMillis, 0,
RollbackListener.NONE);
}
}
}
......@@ -305,7 +306,7 @@ public class TransactionStore {
timeoutMillis = this.timeoutMillis;
}
Transaction transaction = registerTransaction(0, Transaction.STATUS_OPEN, null, 0,
timeoutMillis, ownerId, listener);
timeoutMillis, ownerId, listener);
return transaction;
}
......@@ -336,7 +337,7 @@ public class TransactionStore {
} while(!success);
Transaction transaction = new Transaction(this, transactionId, sequenceNo, status, name, logId,
timeoutMillis, ownerId, listener);
timeoutMillis, ownerId, listener);
assert transactions.get(transactionId) == null;
transactions.set(transactionId, transaction);
......
......@@ -15,9 +15,9 @@ import org.h2.mvstore.MVMap;
public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue> {
private final int mapId;
private final Object key;
final Object value;
final Object value;
private final Transaction transaction;
long undoKey;
long undoKey;
private Transaction blockingTransaction;
private MVMap.Decision decision;
......@@ -49,10 +49,11 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
logIt(existingValue.value == null ? null : VersionedValue.getInstance(existingValue.value));
decision = MVMap.Decision.PUT;
} else if(fetchTransaction(blockingId) == null) {
// condition above means transaction has been committed/rplled back and closed by now
// condition above means transaction has been committed/rolled back and closed by now
decision = MVMap.Decision.REPEAT;
} else {
// this entry comes from a different transaction, and this transaction is not committed yet
// this entry comes from a different transaction, and this
// transaction is not committed yet
// should wait on blockingTransaction that was determined earlier
decision = MVMap.Decision.ABORT;
}
......
......@@ -11,8 +11,9 @@ import java.util.BitSet;
* Class VersionedBitSet extends standard BitSet to add a version field.
* This will allow bit set and version to be changed atomically.
*/
final class VersionedBitSet extends BitSet
{
final class VersionedBitSet extends BitSet {
private static final long serialVersionUID = 1L;
private long version;
public VersionedBitSet() {}
......
......@@ -35,7 +35,7 @@ public class VersionedValue {
return new Uncommitted(operationId, value, committedValue);
}
private VersionedValue(Object value) {
VersionedValue(Object value) {
this.value = value;
}
......@@ -107,7 +107,7 @@ public class VersionedValue {
if(obj == null) return 0;
VersionedValue v = (VersionedValue) obj;
int res = Constants.MEMORY_OBJECT + 8 + 2 * Constants.MEMORY_POINTER +
getValMemory(v.value);
getValMemory(v.value);
if (v.getOperationId() != 0) {
res += getValMemory(v.getCommittedValue());
}
......
......@@ -174,6 +174,7 @@
90141=#Serializer cannot be changed because there is a data table: {0}
90142=#Step size must not be zero
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Obecná chyba: {0}
HY004=Neznámý datový typ: {0}
HYC00=Vlastnost není podporována: {0}
......
......@@ -174,6 +174,7 @@
90141=Serialisierer kann nicht geändert werden wenn eine Daten-Tabelle existiert: {0}
90142=Schrittgrösse darf nicht 0 sein
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Allgemeiner Fehler: {0}
HY004=Unbekannter Datentyp: {0}
HYC00=Dieses Feature wird nicht unterstützt: {0}
......
......@@ -174,6 +174,7 @@
90141=#Serializer cannot be changed because there is a data table: {0}
90142=#Step size must not be zero
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Error General : {0}
HY004=Tipo de dato desconocido : {0}
HYC00=Caracteristica no soportada: {0}
......
......@@ -174,6 +174,7 @@
90141=Le sérialiseur ne peut être changé parce que il y a des données dans la table: {0}
90142=La taille de l'étape ne doit pas être de 0
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Erreur générale: {0}
HY004=Type de données inconnu: {0}
HYC00=Fonctionnalité non supportée: {0}
......
......@@ -174,6 +174,7 @@
90141=データテーブル {0} があるため、シリアライザを変更することはできません
90142=ステップサイズに0は指定できません
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=一般エラー: {0}
HY004=不明なデータ型: {0}
HYC00=機能はサポートされていません: {0}
......
......@@ -174,6 +174,7 @@
90141=Serializator nie może być zmieniony ponieważ istnieje tabela z danymi: {0}
90142=#Step size must not be zero
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Błąd ogólny: {0}
HY004=Nieznany typ danych: {0}
HYC00=Cecha nie jest wspierana: {0}
......
......@@ -174,6 +174,7 @@
90141=#Serializer cannot be changed because there is a data table: {0}
90142=#Step size must not be zero
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Erro geral: {0}
HY004=Tipo de dados desconhecido: {0}
HYC00=Recurso não suportado: {0}
......
......@@ -174,6 +174,7 @@
90141=Serializer не может быть изменен, потому что есть таблица данных: {0}
90142=Размер шага не должен быть равен нулю
90143=Строка {1} не найдена в первичном индексе {0}
90144=Внешняя аутентификация не включена в базе данных {0}
HY000=Внутренняя ошибка: {0}
HY004=Неизвестный тип данных: {0}
HYC00=Данная функция не поддерживается: {0}
......
......@@ -174,6 +174,7 @@
90141=#Serializer cannot be changed because there is a data table: {0}
90142=#Step size must not be zero
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=Všeobecná chyba: {0}
HY004=Neznámy dátový typ: {0}
HYC00=Vlastnosť nie je podporovaná: {0}
......
......@@ -174,6 +174,7 @@
90141=#Serializer cannot be changed because there is a data table: {0}
90142=#Step size must not be zero
90143=#Row {1} not found in primary index {0}
90144=#Authenticator not enabled on database {0}
HY000=常规错误: {0}
HY004=位置数据类型: {0}
HYC00=不支持的特性: {0}
......
......@@ -10,6 +10,7 @@ package org.h2.security.auth;
*
*/
public class AuthConfigException extends RuntimeException {
private static final long serialVersionUID = 1L;
public AuthConfigException() {
super();
......
......@@ -9,6 +9,7 @@ package org.h2.security.auth;
* Exception thrown in case of errors during authentication
*/
public class AuthenticationException extends Exception {
private static final long serialVersionUID = 1L;
public AuthenticationException() {
super();
......
......@@ -27,8 +27,8 @@ public class AuthenticationInfo {
public AuthenticationInfo(ConnectionInfo connectionInfo) {
this.connectionInfo = connectionInfo;
this.realm = connectionInfo.getProperty("AUTHREALM", null);
if (this.realm!=null) {
this.realm=StringUtils.toUpperEnglish(this.realm);
if (this.realm != null) {
this.realm = StringUtils.toUpperEnglish(this.realm);
}
this.password = connectionInfo.getProperty("AUTHZPWD", null);
}
......@@ -50,15 +50,16 @@ public class AuthenticationInfo {
}
public String getFullyQualifiedName() {
if (realm==null) {
return connectionInfo.getUserName();
if (realm == null) {
return connectionInfo.getUserName();
} else {
return connectionInfo.getUserName()+"@"+realm;
return connectionInfo.getUserName() + "@" + realm;
}
}
/**
* get nested identity
*
* @return
*/
public Object getNestedIdentity() {
......@@ -66,8 +67,11 @@ public class AuthenticationInfo {
}
/**
* Method used by authenticators to hold informations about authenticated user
* @param nestedIdentity = nested identity object
* Method used by authenticators to hold informations about authenticated
* user
*
* @param nestedIdentity
* = nested identity object
*/
public void setNestedIdentity(Object nestedIdentity) {
this.nestedIdentity = nestedIdentity;
......
......@@ -9,25 +9,27 @@ import org.h2.engine.Database;
import org.h2.engine.User;
/**
* Low level interface to implement full authentication process
* Low level interface to implement full authentication process.
*/
public interface Authenticator {
/**
* perform user authentication
*
* Perform user authentication.
*
* @param authenticationInfo
* @param database
* @return valid database user or null if user doesn't exists in the database
* @return valid database user or null if user doesn't exists in the
* database
* @throws AuthenticationException
*/
User authenticate(AuthenticationInfo authenticationInfo, Database database) throws AuthenticationException;
/**
* Initialize the authenticator. This method is invoked by databases when the authenticator is set
* when the authenticator is set.
* @param database = target database
* Initialize the authenticator. This method is invoked by databases when
* the authenticator is set when the authenticator is set.
*
* @param database
* target database
* @throws AuthConfigException
*/
void init(Database database) throws AuthConfigException;
......
......@@ -20,19 +20,19 @@ public class ConfigProperties {
private Map<String, String> properties;
public ConfigProperties() {
properties = new HashMap<>();
properties = new HashMap<>();
}
public ConfigProperties(PropertyConfig...configProperties) {
this(configProperties==null?null:Arrays.asList(configProperties));
public ConfigProperties(PropertyConfig... configProperties) {
this(configProperties == null ? null : Arrays.asList(configProperties));
}
public ConfigProperties(Collection<PropertyConfig> configProperties) {
properties = new HashMap<>();
if (properties != null) {
for (PropertyConfig currentProperty : configProperties) {
if (properties.put(currentProperty.getName(), currentProperty.getValue())!=null) {
throw new AuthConfigException("duplicate property "+currentProperty.getName());
if (properties.put(currentProperty.getName(), currentProperty.getValue()) != null) {
throw new AuthConfigException("duplicate property " + currentProperty.getName());
}
}
}
......@@ -49,7 +49,7 @@ public class ConfigProperties {
public String getStringValue(String name) {
String result = properties.get(name);
if (result == null) {
throw new AuthConfigException("missing config property "+name);
throw new AuthConfigException("missing config property " + name);
}
return result;
}
......@@ -65,7 +65,7 @@ public class ConfigProperties {
public int getIntValue(String name) {
String result = properties.get(name);
if (result == null) {
throw new AuthConfigException("missing config property "+name);
throw new AuthConfigException("missing config property " + name);
}
return Integer.parseInt(result);
}
......
......@@ -33,20 +33,21 @@ import org.h2.util.StringUtils;
* Default authenticator implementation.
* <p>
* When client connectionInfo contains property AUTHREALM={realName} credentials
* (typically user id and password) are validated by
* by {@link org.h2.api.CredentialsValidator} configured for that realm.
* (typically user id and password) are validated by by
* {@link org.h2.api.CredentialsValidator} configured for that realm.
* </p>
* <p>
* <p>
* When client connectionInfo doesn't contains AUTHREALM property credentials
* are validated internally on the database
* </p>
* are validated internally on the database
* </p>
* <p>
* Rights assignment can be managed through {@link org.h2.api.UserToRolesMapper}
* </p>
* <p>
* Default configuration has a realm H2 that validate credentials through JAAS api (appName=h2).
* To customize configuration set h2.authConfigFile system property to refer a valid h2auth.xml config file
* </p>
* Default configuration has a realm H2 that validate credentials through JAAS
* api (appName=h2). To customize configuration set h2.authConfigFile system
* property to refer a valid h2auth.xml config file
* </p>
*/
public class DefaultAuthenticator implements Authenticator {
......@@ -69,8 +70,8 @@ public class DefaultAuthenticator implements Authenticator {
private static DefaultAuthenticator instance;
protected static final DefaultAuthenticator getInstance() {
if (instance==null) {
instance= new DefaultAuthenticator();
if (instance == null) {
instance = new DefaultAuthenticator();
}
return instance;
}
......@@ -84,9 +85,9 @@ public class DefaultAuthenticator implements Authenticator {
/**
* Create authenticator and optionally skip the default configuration. This
* option is useful when the authenticator is configured at code level
*
*
* @param skipDefaultInitialization
* if true default initialization is skipped
* if true default initialization is skipped
*/
public DefaultAuthenticator(boolean skipDefaultInitialization) {
this.skipDefaultInitialization = skipDefaultInitialization;
......@@ -94,7 +95,7 @@ public class DefaultAuthenticator implements Authenticator {
/**
* If set save users externals defined during the authentication.
*
*
* @return
*/
public boolean isPersistUsers() {
......@@ -107,7 +108,7 @@ public class DefaultAuthenticator implements Authenticator {
/**
* If set create external users in the database if not present.
*
*
* @return
*/
public boolean isAllowUserRegistration() {
......@@ -119,9 +120,9 @@ public class DefaultAuthenticator implements Authenticator {
}
/**
* When set create roles not found in the database. If not set roles not found
* in the database are silently skipped
*
* When set create roles not found in the database. If not set roles not
* found in the database are silently skipped
*
* @return
*/
public boolean isCreateMissingRoles() {
......@@ -134,9 +135,11 @@ public class DefaultAuthenticator implements Authenticator {
/**
* Add an authentication realm. Realms are case insensitive
*
* @param name realm name
* @param credentialsValidator credentials validator for realm
*
* @param name
* realm name
* @param credentialsValidator
* credentials validator for realm
*/
public void addRealm(String name, CredentialsValidator credentialsValidator) {
realms.put(StringUtils.toUpperEnglish(name), credentialsValidator);
......@@ -144,7 +147,7 @@ public class DefaultAuthenticator implements Authenticator {
/**
* UserToRoleMappers assign roles to authenticated users
*
*
* @return current UserToRoleMappers active
*/
public List<UserToRolesMapper> getUserToRolesMappers() {
......@@ -160,17 +163,20 @@ public class DefaultAuthenticator implements Authenticator {
}
/**
* Initializes the authenticator (it is called by AuthententicationManager)
*
* this method is skipped if skipDefaultInitialization is set
* Order of initialization is
* <ol>
* <li>Check h2.authConfigFile system property.</li>
* <li>Use the default configuration hard coded</li>
* </ol>
* @param database where authenticator is initialized
* Initializes the authenticator.
*
* this method is skipped if skipDefaultInitialization is set Order of
* initialization is
* <ol>
* <li>Check h2.authConfigFile system property.</li>
* <li>Use the default configuration hard coded</li>
* </ol>
*
* @param database
* where authenticator is initialized
* @throws AuthConfigException
*/
@Override
public void init(Database database) throws AuthConfigException {
if (skipDefaultInitialization) {
return;
......@@ -182,13 +188,14 @@ public class DefaultAuthenticator implements Authenticator {
if (initialized) {
return;
}
Trace trace=database.getTrace(Trace.DATABASE);
Trace trace = database.getTrace(Trace.DATABASE);
URL h2AuthenticatorConfigurationUrl = null;
try {
String configFile = SysProperties.AUTH_CONFIG_FILE;
if (configFile != null) {
if (trace.isDebugEnabled()) {
trace.debug("DefaultAuthenticator.config: configuration read from system property h2auth.configurationfile={0}", configFile);
trace.debug("DefaultAuthenticator.config: configuration read from system property"
+ " h2auth.configurationfile={0}", configFile);
}
h2AuthenticatorConfigurationUrl = new URL(configFile);
}
......@@ -201,11 +208,12 @@ public class DefaultAuthenticator implements Authenticator {
configureFromUrl(h2AuthenticatorConfigurationUrl);
}
} catch (Exception e) {
trace.error(e, "DefaultAuthenticator.config: an error occurred during configuration from {0} ", h2AuthenticatorConfigurationUrl);
throw new AuthConfigException("Failed to configure authentication from " + h2AuthenticatorConfigurationUrl,
e);
trace.error(e, "DefaultAuthenticator.config: an error occurred during configuration from {0} ",
h2AuthenticatorConfigurationUrl);
throw new AuthConfigException(
"Failed to configure authentication from " + h2AuthenticatorConfigurationUrl, e);
}
initialized=true;
initialized = true;
}
}
......@@ -223,8 +231,9 @@ public class DefaultAuthenticator implements Authenticator {
/**
* Configure the authenticator from a configuration file
*
* @param configUrl URL of configuration file
*
* @param configUrl
* URL of configuration file
* @throws Exception
*/
public void configureFromUrl(URL configUrl) throws Exception {
......
......@@ -31,7 +31,7 @@ public class H2AuthConfig {
public void setAllowUserRegistration(boolean allowUserRegistration) {
this.allowUserRegistration = allowUserRegistration;
}
@XmlAttribute
boolean createMissingRoles=true;
......
......@@ -23,11 +23,12 @@ public class PropertyConfig {
public PropertyConfig() {
}
public PropertyConfig(String name, String value) {
this.name=name;
this.value=value;
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
......
......@@ -13,6 +13,9 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
/**
* Configuration for authentication realm.
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class RealmConfig {
......
......@@ -13,6 +13,9 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
/**
* Configuration for class that maps users to roles.
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class UserToRolesMapperConfig {
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: Alessandro Ventura
*/
package org.h2.security.auth.impl;
import java.util.Arrays;
......@@ -10,7 +15,7 @@ import org.h2.security.auth.ConfigProperties;
/**
* Assign to user a role based on realm name
*
*
* * <p>
* Configuration parameters:
* </p>
......@@ -25,14 +30,14 @@ public class AssignRealmNameRole implements UserToRolesMapper{
public AssignRealmNameRole() {
this("@%s");
}
public AssignRealmNameRole(String roleNameFormat) {
this.roleNameFormat = roleNameFormat;
}
@Override
public void configure(ConfigProperties configProperties) {
roleNameFormat=configProperties.getStringValue("roleNameFormat",roleNameFormat);
roleNameFormat=configProperties.getStringValue("roleNameFormat",roleNameFormat);
}
@Override
......
......@@ -19,8 +19,8 @@ import org.h2.security.auth.AuthenticationInfo;
import org.h2.security.auth.ConfigProperties;
/**
* Validate credentials by using standard Java Authentication and Authorization Service
*
* Validate credentials by using standard Java Authentication and Authorization Service
*
* <p>
* Configuration parameters:
* </p>
......@@ -49,17 +49,17 @@ public class JaasCredentialsValidator implements CredentialsValidator {
@Override
public void configure(ConfigProperties configProperties) {
appName=configProperties.getStringValue("appName",appName);
appName=configProperties.getStringValue("appName",appName);
}
class AuthenticationInfoCallbackHandler implements CallbackHandler {
AuthenticationInfo authenticationInfo;
AuthenticationInfoCallbackHandler(AuthenticationInfo authenticationInfo) {
this.authenticationInfo = authenticationInfo;
}
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
......@@ -70,12 +70,13 @@ public class JaasCredentialsValidator implements CredentialsValidator {
}
}
}
}
@Override
public boolean validateCredentials(AuthenticationInfo authenticationInfo) throws Exception {
LoginContext loginContext = new LoginContext(appName,new AuthenticationInfoCallbackHandler(authenticationInfo));
LoginContext loginContext = new LoginContext(appName,
new AuthenticationInfoCallbackHandler(authenticationInfo));
loginContext.login();
authenticationInfo.setNestedIdentity(loginContext.getSubject());
return true;
......
......@@ -21,9 +21,10 @@ import org.h2.security.auth.ConfigProperties;
* Configuration parameters:
* </p>
* <ul>
* <li>bindDnPattern bind dn pattern with %u instead of username (example: uid=%u,ou=users,dc=example,dc=com)</li>
* <li>bindDnPattern bind dn pattern with %u instead of username
* (example: uid=%u,ou=users,dc=example,dc=com)</li>
* <li>host ldap server</li>
* <li>port of ldap service; optional, by default 389 for unsecure, 636 for secure</li>
* <li>port of ldap service; optional, by default 389 for insecure, 636 for secure</li>
* <li>secure, optional by default is true (use SSL)</li>
* </ul>
*/
......
......@@ -22,19 +22,19 @@ import org.h2.security.auth.ConfigProperties;
* <ul>
* <li>roles role list separated by comma</li>
* </ul>
*
*
*/
public class StaticRolesMapper implements UserToRolesMapper {
private Collection<String> roles;
public StaticRolesMapper() {
}
public StaticRolesMapper(String... roles) {
this.roles=Arrays.asList(roles);
}
@Override
public void configure(ConfigProperties configProperties) {
String rolesString=configProperties.getStringValue("roles", "");
......
/*
* Copyright 2004-2018 H2 Group. Mul tiple-Licensed under the MPL 2.0,
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: Alessandro Ventura
*/
......@@ -17,7 +17,7 @@ import org.h2.util.StringUtils;
import org.h2.util.Utils;
/**
* This credentials validator matches the user and password with the configured
* This credentials validator matches the user and password with the configured
* Usage should be limited to test purposes
*
*/
......@@ -30,7 +30,7 @@ public class StaticUserCredentialsValidator implements CredentialsValidator {
public StaticUserCredentialsValidator() {
}
public StaticUserCredentialsValidator(String userNamePattern,String password) {
if (userNamePattern!=null) {
this.userNamePattern=Pattern.compile(userNamePattern.toUpperCase());
......@@ -38,10 +38,9 @@ public class StaticUserCredentialsValidator implements CredentialsValidator {
salt=MathUtils.secureRandomBytes(256);
hashWithSalt=SHA256.getHashWithSalt(password.getBytes(), salt);
}
@Override
public boolean validateCredentials(AuthenticationInfo authenticationInfo) throws AuthenticationException {
if (userNamePattern!=null) {
if (!userNamePattern.matcher(authenticationInfo.getUserName()).matches()) {
return false;
......@@ -50,14 +49,15 @@ public class StaticUserCredentialsValidator implements CredentialsValidator {
if (password!=null) {
return password.equals(authenticationInfo.getPassword());
}
return Utils.compareSecure(hashWithSalt,SHA256.getHashWithSalt(authenticationInfo.getPassword().getBytes(), salt));
return Utils.compareSecure(hashWithSalt,
SHA256.getHashWithSalt(authenticationInfo.getPassword().getBytes(), salt));
}
@Override
public void configure(ConfigProperties configProperties) {
String userNamePatternString=configProperties.getStringValue("userNamePattern",null);
if (userNamePatternString!=null) {
userNamePattern=userNamePattern.compile(userNamePatternString);
userNamePattern = Pattern.compile(userNamePatternString);
}
password=configProperties.getStringValue("password",password);
String saltString =configProperties.getStringValue("salt",null);
......@@ -66,7 +66,7 @@ public class StaticUserCredentialsValidator implements CredentialsValidator {
}
String hashString=configProperties.getStringValue("hash", null);
if (hashString!=null) {
hashWithSalt = SHA256.getHashWithSalt(StringUtils.convertHexToBytes(hashString), salt);
hashWithSalt = SHA256.getHashWithSalt(StringUtils.convertHexToBytes(hashString), salt);
}
}
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0, Version 1.0,
and under the Eclipse Public License, Version 1.0
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"><p>
Authentication classes.
</p></body></html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0, Version 1.0,
and under the Eclipse Public License, Version 1.0
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"><p>
Authentication classes.
</p></body></html>
\ No newline at end of file
......@@ -1072,8 +1072,8 @@ public class MetaTable extends Table {
Long.toString(fs.getWriteCount()));
add(rows, "info.FILE_READ",
Long.toString(fs.getReadCount()));
int updateFailureRatio = (int)(10000 * mvStore.getStore().getUpdateFailureRatio());
add(rows, "info.UPDATE_FAILURE_PERCENT", "" + updateFailureRatio / 100 + "." + updateFailureRatio % 100 + "%");
add(rows, "info.UPDATE_FAILURE_PERCENT",
String.format(Locale.ENGLISH, "%.2f%%", 100 * mvStore.getStore().getUpdateFailureRatio()));
long size;
try {
size = fs.getFile().size();
......
......@@ -510,7 +510,8 @@ public abstract class Table extends SchemaObjectBase {
try {
removeRow(session, o);
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1 || e.getErrorCode() == ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1) {
if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1
|| e.getErrorCode() == ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1) {
session.rollbackTo(rollback, false);
session.startStatementWithinTransaction();
rollback = session.setSavepoint();
......
......@@ -15,7 +15,7 @@ import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
/**
* Dummy login module used for test cases
* Dummy login module used for test cases
*/
public class MyLoginModule implements LoginModule{
......
......@@ -31,6 +31,9 @@ import org.h2.security.auth.impl.StaticRolesMapper;
import org.h2.security.auth.impl.StaticUserCredentialsValidator;
import org.h2.test.TestBase;
/**
* Test for custom authentication.
*/
public class TestAuthentication extends TestBase {
public static void main(String... a) throws Exception {
......@@ -123,7 +126,7 @@ public class TestAuthentication extends TestBase {
protected void allTests() throws Exception {
testInvalidPassword();
testExternalUserWihoutRealm();
testExternalUserWithoutRealm();
testExternalUser();
testAssignRealNameRole();
testStaticRole();
......@@ -143,7 +146,7 @@ public class TestAuthentication extends TestBase {
}
}
protected void testExternalUserWihoutRealm() throws Exception {
protected void testExternalUserWithoutRealm() throws Exception {
try {
Connection wrongLoginConnection = DriverManager.getConnection(getDatabaseURL(), getExternalUser(),
getExternalUserPassword());
......@@ -166,7 +169,7 @@ public class TestAuthentication extends TestBase {
}
protected void testDatasource() throws Exception {
DataSource dataSource = JdbcConnectionPool.create(
getDatabaseURL() + ";AUTHREALM=" + getRealmName().toUpperCase(), getExternalUser(),
getExternalUserPassword());
......@@ -221,7 +224,8 @@ public class TestAuthentication extends TestBase {
try {
try {
Connection wrongLoginConnection = DriverManager.getConnection(
getDatabaseURL() + ";AUTHREALM=" + getRealmName().toUpperCase(), "___" + getExternalUser(), "");
getDatabaseURL() + ";AUTHREALM=" + getRealmName().toUpperCase(), "___" + getExternalUser(),
"");
wrongLoginConnection.close();
throw new Exception(
"unregistered external users should not be able to login when allowUserRegistration=false");
......@@ -241,7 +245,7 @@ public class TestAuthentication extends TestBase {
defaultAuthenticator.setAllowUserRegistration(initialValueAllow);
}
}
public void testStaticUserCredentials() throws Exception {
String userName="STATICUSER3";
Connection rightConnection = DriverManager.getConnection(
......@@ -254,15 +258,15 @@ public class TestAuthentication extends TestBase {
rightConnection.close();
}
}
protected void testSet() throws Exception{
Connection rightConnection = DriverManager.getConnection(
getDatabaseURL()+";AUTHENTICATOR=FALSE","DBA","");
try {
try {
testExternalUser();
throw new Exception("External user shouldnt be allowed");
}catch (Exception e) {
throw new Exception("External user shouldn't be allowed");
} catch (Exception e) {
}
} finally {
configureAuthentication(database);
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0, Version 1.0,
and under the Eclipse Public License, Version 1.0
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"><p>
Tests for custom authentication.
</p></body></html>
\ No newline at end of file
......@@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import org.h2.message.TraceSystem;
import org.h2.store.FileLister;
import org.h2.test.TestBase;
......@@ -297,6 +298,11 @@ public class TestBigResult extends TestBase {
}
private void testLOB() throws SQLException {
if (config.traceLevelFile == TraceSystem.DEBUG) {
// Trace system on this level can throw OOME with such large
// arguments as used in this test.
return;
}
deleteDb("bigResult");
Connection conn = getConnection("bigResult");
Statement stat = conn.createStatement();
......
......@@ -66,7 +66,6 @@ public class TestMvcc4 extends TestBase {
c1.setAutoCommit(false);
//Fire off a concurrent update.
final Thread mainThread = Thread.currentThread();
final CountDownLatch executedUpdate = new CountDownLatch(1);
new Thread() {
@Override
......@@ -83,7 +82,8 @@ public class TestMvcc4 extends TestBase {
executedUpdate.countDown();
// interrogate new "blocker_id" metatable field instead of
// relying on stacktraces!? to determine when session is blocking
PreparedStatement stmt = c2.prepareStatement("SELECT * FROM INFORMATION_SCHEMA.SESSIONS WHERE BLOCKER_ID = SESSION_ID()");
PreparedStatement stmt = c2.prepareStatement(
"SELECT * FROM INFORMATION_SCHEMA.SESSIONS WHERE BLOCKER_ID = SESSION_ID()");
ResultSet resultSet;
do {
resultSet = stmt.executeQuery();
......
......@@ -39,7 +39,7 @@ public class TestMvccMultiThreaded2 extends TestBase {
test.test();
}
private int getTestDuration() {
int getTestDuration() {
// to save some testing time
return config.big ? TEST_TIME_SECONDS : TEST_TIME_SECONDS / 10;
}
......
......@@ -299,7 +299,8 @@ public class TestScript extends TestBase {
private void process(String sql, boolean allowReconnect) throws Exception {
if (allowReconnect && reconnectOften) {
if (!containsTempTables() && ((JdbcConnection) conn).isRegularMode() && conn.getSchema().equals("PUBLIC")) {
if (!containsTempTables() && ((JdbcConnection) conn).isRegularMode()
&& conn.getSchema().equals("PUBLIC")) {
boolean autocommit = conn.getAutoCommit();
if (autocommit && random.nextInt(10) < 1) {
// reconnect 10% of the time
......
......@@ -404,7 +404,7 @@ public class TestTransactionStore extends TestBase {
}
}
// re-open TransactionStore, because we rolled back
// underlying MVStore without rolling back TranactionStore
// underlying MVStore without rolling back TransactionStore
s.close();
s = MVStore.open(fileName);
ts = new TransactionStore(s);
......
......@@ -86,7 +86,6 @@ public class TestCrashAPI extends TestBase implements Runnable {
}
@Override
@SuppressWarnings("deprecation")
public void run() {
while (--maxWait > 0) {
try {
......@@ -103,11 +102,11 @@ public class TestCrashAPI extends TestBase implements Runnable {
if (maxWait == 0 && running) {
objects.clear();
if (running) {
println("stopping (force)...");
println("stopping (trying to interrupt)...");
for (StackTraceElement e : mainThread.getStackTrace()) {
System.out.println(e.toString());
}
mainThread.stop(new SQLException("stop"));
mainThread.interrupt();
}
}
}
......
......@@ -777,4 +777,9 @@ geometries sourceschema destschema generatedcolumn alphanumerically usages
sizable instantiates renders sdt txcommit unhelpful optimiser treats rejects referring untrusted computes vacate inverted
reordered colliding evgenij archaic invocations apostrophe hypothetically testref ryazanov useless completes highlighting tends degrade
summands minuend subtrahend
summands minuend subtrahend localtime localtimestamp governs unfinished pressure closure discovered victim seemingly
flaw capture coherent removals silence opentransactions picture tokar mailto andrei dur discarded blocker captures txdm
intentionally authenticator authrealm ventura credentials alessandro validator acquisition vital mariadb preventing
ewkt ewkb informations authzpwd realms mappers jaxb realmname configurationfile unmarshal jaas externals customize
authenticators appname interrogate metatable barrier preliminary staticuser staticpassword unregistered inquiry
ldapexample remoteuser assignments djava validators mock relate mapid tighten
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论