Skip to content

Commit

Permalink
Distributed: fixed security problem on user change
Browse files Browse the repository at this point in the history
  • Loading branch information
lvca committed May 24, 2015
1 parent 318cc81 commit f08f910
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 26 deletions.
Expand Up @@ -884,7 +884,7 @@ public OSecurityUser getUser() {
/**
* {@inheritDoc}
*/
public void setUser(OSecurityUser user) {
public void setUser(final OSecurityUser user) {
if (user instanceof OUser) {
OMetadata metadata = getMetadata();
if (metadata != null) {
Expand Down
Expand Up @@ -29,10 +29,10 @@
*
*/
public abstract class OProxedResource<T> {
protected T delegate;
protected ODatabaseDocumentInternal database;
protected final T delegate;
protected final ODatabaseDocumentInternal database;

public OProxedResource(final T iDelegate, final ODatabaseDocumentInternal iDatabase) {
protected OProxedResource(final T iDelegate, final ODatabaseDocumentInternal iDatabase) {
this.delegate = iDelegate;
this.database = iDatabase;
}
Expand Down
Expand Up @@ -36,6 +36,7 @@
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OSchemaShared;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.metadata.security.OSecurityNull;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.storage.OStorage;
import com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage;
Expand Down Expand Up @@ -556,7 +557,7 @@ private Collection<ODocument> getConfiguration() {

private void setUpDatabase() {
newDb.resetInitialization();
newDb.setProperty(ODatabase.OPTIONS.SECURITY.toString(), Boolean.FALSE);
newDb.setProperty(ODatabase.OPTIONS.SECURITY.toString(), OSecurityNull.class);
newDb.open("admin", "nopass");

ODatabaseRecordThreadLocal.INSTANCE.set(newDb);
Expand Down
Expand Up @@ -28,6 +28,7 @@
import com.orientechnologies.orient.core.db.ODatabase;
import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.exception.OSecurityException;
import com.orientechnologies.orient.core.index.OIndexManager;
import com.orientechnologies.orient.core.index.OIndexManagerProxy;
import com.orientechnologies.orient.core.index.OIndexManagerRemote;
Expand All @@ -40,7 +41,6 @@
import com.orientechnologies.orient.core.metadata.schema.OSchemaProxy;
import com.orientechnologies.orient.core.metadata.schema.OSchemaShared;
import com.orientechnologies.orient.core.metadata.security.OSecurity;
import com.orientechnologies.orient.core.metadata.security.OSecurityNull;
import com.orientechnologies.orient.core.metadata.security.OSecurityProxy;
import com.orientechnologies.orient.core.metadata.security.OSecurityShared;
import com.orientechnologies.orient.core.schedule.OSchedulerListener;
Expand Down Expand Up @@ -172,22 +172,29 @@ public OIndexManager call() {
}
}), database);

final Boolean enableSecurity = (Boolean) database.getProperty(ODatabase.OPTIONS.SECURITY.toString());
if (enableSecurity != null && !enableSecurity)
// INSTALL NO SECURITY IMPL
security = new OSecurityNull();
else
security = new OSecurityProxy(database.getStorage().getResource(OSecurity.class.getSimpleName(),
new Callable<OSecurityShared>() {
public OSecurityShared call() {
final OSecurityShared instance = new OSecurityShared();
if (iLoad) {
security = instance;
instance.load();
}
return instance;
security = new OSecurityProxy(database.getStorage().getResource(OSecurity.class.getSimpleName(),
new Callable<OSecurityShared>() {
public OSecurityShared call() {
final OSecurityShared instance = new OSecurityShared();
if (iLoad) {
security = instance;
instance.load();
}
}), database);
return instance;
}
}), database);

final Class<? extends OSecurity> securityClass = (Class<? extends OSecurity>) database.getProperty(ODatabase.OPTIONS.SECURITY
.toString());
if (securityClass != null)
// INSTALL CUSTOM WRAPPED SECURITY
try {
final OSecurity wrapped = security;
security = securityClass.getDeclaredConstructor(OSecurity.class, ODatabaseDocumentInternal.class).newInstance(wrapped,
database);
} catch (Exception e) {
throw new OSecurityException("Cannot install custom security implementation (" + securityClass + ")", e);
}

functionLibrary = new OFunctionLibraryProxy(database.getStorage().getResource(OFunctionLibrary.class.getSimpleName(),
new Callable<OFunctionLibrary>() {
Expand Down
Expand Up @@ -60,6 +60,27 @@
import com.orientechnologies.orient.server.plugin.OServerPlugin;
import com.orientechnologies.orient.server.plugin.OServerPluginInfo;
import com.orientechnologies.orient.server.plugin.OServerPluginManager;
import com.orientechnologies.orient.server.security.OSecurityServerUser;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
Expand Down Expand Up @@ -658,7 +679,7 @@ public ODatabase<?> openDatabase(final String iDbType, final String iDbUrl, fina

// SERVER AUTHENTICATED, BYPASS SECURITY
database.resetInitialization();
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), Boolean.FALSE);
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), OSecurityServerUser.class);
database.open(user, password);
if (data != null) {
data.serverUser = true;
Expand All @@ -685,7 +706,7 @@ public ODatabaseInternal openDatabase(final ODatabaseInternal database) {

// SERVER AUTHENTICATED, BYPASS SECURITY
database.resetInitialization();
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), Boolean.FALSE);
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), OSecurityServerUser.class);
database.open(replicatorUser.name, replicatorUser.password);
}

Expand Down
Expand Up @@ -30,6 +30,7 @@
import com.orientechnologies.orient.core.db.ODatabase;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.exception.OConfigurationException;
import com.orientechnologies.orient.core.metadata.security.OSecurityNull;
import com.orientechnologies.orient.server.OServer;
import com.orientechnologies.orient.server.config.OServerParameterConfiguration;
import com.orientechnologies.orient.server.plugin.OServerPluginAbstract;
Expand Down Expand Up @@ -150,7 +151,7 @@ else if (iVariable.startsWith(VARIABLES.DATE.toString())) {
try {

db = new ODatabaseDocumentTx(dbName.getValue());
db.setProperty(ODatabase.OPTIONS.SECURITY.toString(), Boolean.FALSE);
db.setProperty(ODatabase.OPTIONS.SECURITY.toString(), OSecurityNull.class);
db.open("admin", "aaa");

final long begin = System.currentTimeMillis();
Expand Down
Expand Up @@ -92,6 +92,7 @@
import com.orientechnologies.orient.server.network.OServerNetworkListener;
import com.orientechnologies.orient.server.plugin.OServerPlugin;
import com.orientechnologies.orient.server.plugin.OServerPluginHelper;
import com.orientechnologies.orient.server.security.OSecurityServerUser;
import com.orientechnologies.orient.server.tx.OTransactionOptimisticProxy;

import java.io.IOException;
Expand Down Expand Up @@ -198,7 +199,7 @@ protected void onBeforeRequest() throws IOException {
final ODatabaseDocumentTx database = new ODatabaseDocumentTx(type + ":" + db);
if (connection.data.serverUser) {
database.resetInitialization();
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), Boolean.FALSE);
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), OSecurityServerUser.class);
database.open(connection.data.serverUsername, null);
} else
database.open(token);
Expand Down Expand Up @@ -499,7 +500,7 @@ protected ODatabase<?> openDatabase(final ODatabaseInternal<?> database, final S

// SERVER AUTHENTICATED, BYPASS SECURITY
database.resetInitialization();
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), Boolean.FALSE);
database.setProperty(ODatabase.OPTIONS.SECURITY.toString(), OSecurityServerUser.class);
database.open(iUser, iPassword);
}
}
Expand Down
@@ -0,0 +1,169 @@
/*
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* *
* * For more information: http://www.orientechnologies.com
*
*/
package com.orientechnologies.orient.server.security;

import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.OProxedResource;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.metadata.security.OSecurity;
import com.orientechnologies.orient.core.metadata.security.OSecurityRole;
import com.orientechnologies.orient.core.metadata.security.OToken;
import com.orientechnologies.orient.core.metadata.security.OUser;
import com.orientechnologies.orient.core.record.impl.ODocument;

import java.util.List;
import java.util.Set;

/**
* Security injected by server. This implementation is still able to change use to a database user.
*
* @author Luca Garulli
*
*/
public class OSecurityServerUser extends OProxedResource<OSecurity> implements OSecurity {
public OSecurityServerUser(final OSecurity iDelegate, final ODatabaseDocumentInternal iDatabase) {
super(iDelegate, iDatabase);
}

@Override
public boolean isAllowed(final Set<OIdentifiable> iAllowAll, final Set<OIdentifiable> iAllowOperation) {
return delegate.isAllowed(iAllowAll, iAllowOperation);
}

public OIdentifiable allowUser(final ODocument iDocument, final String iAllowFieldName, final String iUserName) {
return delegate.allowUser(iDocument, iAllowFieldName, iUserName);
}

public OIdentifiable allowRole(final ODocument iDocument, final String iAllowFieldName, final String iRoleName) {
return delegate.allowRole(iDocument, iAllowFieldName, iRoleName);
}

@Override
public OIdentifiable allowIdentity(ODocument iDocument, String iAllowFieldName, OIdentifiable iId) {
return delegate.allowIdentity(iDocument, iAllowFieldName, iId);
}

public OIdentifiable disallowUser(final ODocument iDocument, final String iAllowFieldName, final String iUserName) {
return delegate.disallowUser(iDocument, iAllowFieldName, iUserName);
}

public OIdentifiable disallowRole(final ODocument iDocument, final String iAllowFieldName, final String iRoleName) {
return delegate.disallowRole(iDocument, iAllowFieldName, iRoleName);
}

@Override
public OIdentifiable disallowIdentity(ODocument iDocument, String iAllowFieldName, OIdentifiable iId) {
return delegate.disallowIdentity(iDocument, iAllowFieldName, iId);
}

public OUser create() {
return delegate.create();
}

public void load() {
delegate.load();
}

public void close(boolean onDelete) {
if (delegate != null)
delegate.close(false);
}

public OUser authenticate(final String iUsername, final String iUserPassword) {
return null;
}

public OUser authenticate(final OToken authToken) {
return null;
}

public OUser getUser(final String iUserName) {
return delegate.getUser(iUserName);
}

public OUser getUser(final ORID iUserId) {
return delegate.getUser(iUserId);
}

public OUser createUser(final String iUserName, final String iUserPassword, final String... iRoles) {
return delegate.createUser(iUserName, iUserPassword, iRoles);
}

public OUser createUser(final String iUserName, final String iUserPassword, final ORole... iRoles) {
return delegate.createUser(iUserName, iUserPassword, iRoles);
}

public ORole getRole(final String iRoleName) {
return delegate.getRole(iRoleName);
}

public ORole getRole(final OIdentifiable iRole) {
return delegate.getRole(iRole);
}

public ORole createRole(final String iRoleName, final OSecurityRole.ALLOW_MODES iAllowMode) {
return delegate.createRole(iRoleName, iAllowMode);
}

public ORole createRole(final String iRoleName, final ORole iParent, final OSecurityRole.ALLOW_MODES iAllowMode) {
return delegate.createRole(iRoleName, iParent, iAllowMode);
}

public List<ODocument> getAllUsers() {
return delegate.getAllUsers();
}

public List<ODocument> getAllRoles() {
return delegate.getAllRoles();
}

public String toString() {
return delegate.toString();
}

public boolean dropUser(final String iUserName) {
return delegate.dropUser(iUserName);
}

public boolean dropRole(final String iRoleName) {
return delegate.dropRole(iRoleName);
}

public void createClassTrigger() {
delegate.createClassTrigger();
}

@Override
public OSecurity getUnderlying() {
return delegate;
}

@Override
public long getVersion() {
return delegate.getVersion();
}

@Override
public void incrementVersion() {
delegate.incrementVersion();
}
}

0 comments on commit f08f910

Please sign in to comment.