blob: 8282b46dc8e7910be1944ec724ab935ac647ae3d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You 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.
*/
package org.apache.geode.security;
import java.security.Principal;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import org.apache.geode.DataSerializable;
import org.apache.geode.DataSerializer;
import org.apache.geode.Instantiator;
import org.apache.geode.LogWriter;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.operations.OperationContext;
import org.apache.geode.cache.operations.OperationContext.OperationCode;
import org.apache.geode.cache.operations.PutAllOperationContext;
import org.apache.geode.cache.operations.PutOperationContext;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.HeapDataOutputStream;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.serialization.Version;
/**
* An authorization implementation for testing that changes a string value in pre-operation phase to
* add an integer denoting which <code>Principal</code>s would be allowed to get that object.
*
* @since GemFire 5.5
*/
public class FilterPreAuthorization implements AccessControl {
private LogWriter logger;
static {
Instantiator.register(new Instantiator(ObjectWithAuthz.class, ObjectWithAuthz.CLASSID) {
@Override
public DataSerializable newInstance() {
return new ObjectWithAuthz();
}
}, false);
}
public FilterPreAuthorization() {
this.logger = null;
}
public static AccessControl create() {
return new FilterPreAuthorization();
}
@Override
public void init(Principal principal, DistributedMember remoteMember, Cache cache)
throws NotAuthorizedException {
this.logger = cache.getSecurityLogger();
}
@Override
public boolean authorizeOperation(String regionName, OperationContext context) {
assert !context.isPostOperation();
OperationCode opCode = context.getOperationCode();
if (opCode.isPut()) {
PutOperationContext createContext = (PutOperationContext) context;
// byte[] serializedValue = createContext.getSerializedValue();
byte[] serializedValue = null;
Object value = createContext.getValue();
int valLength;
byte lastByte;
if (value == null) {
// This means serializedValue too is null.
valLength = 0;
lastByte = 0;
} else {
if (value instanceof byte[]) {
serializedValue = (byte[]) value;
valLength = serializedValue.length;
lastByte = serializedValue[valLength - 1];
} else {
ObjectWithAuthz authzObj = new ObjectWithAuthz(value, Integer.valueOf(value.hashCode()));
createContext.setValue(authzObj, true);
return true;
}
}
HeapDataOutputStream hos = new HeapDataOutputStream(valLength + 32, Version.CURRENT);
try {
InternalDataSerializer.writeUserDataSerializableHeader(ObjectWithAuthz.CLASSID, hos);
if (serializedValue != null) {
hos.write(serializedValue);
}
// Some value that determines the Principals that can get this object.
Integer allowedIndex = Integer.valueOf(lastByte);
DataSerializer.writeObject(allowedIndex, hos);
} catch (Exception ex) {
return false;
}
createContext.setSerializedValue(hos.toByteArray(), true);
if (this.logger.fineEnabled())
this.logger.fine("FilterPreAuthorization: added authorization " + "info for key: "
+ createContext.getKey());
} else if (opCode.isPutAll()) {
PutAllOperationContext createContext = (PutAllOperationContext) context;
Map map = createContext.getMap();
Collection entries = map.entrySet();
Iterator iterator = entries.iterator();
Map.Entry mapEntry = null;
while (iterator.hasNext()) {
mapEntry = (Map.Entry) iterator.next();
String currkey = (String) mapEntry.getKey();
Object value = mapEntry.getValue();
Integer authCode;
if (value != null) {
String valStr = value.toString();
authCode = (int) valStr.charAt(valStr.length() - 1);
} else {
authCode = 0;
}
ObjectWithAuthz authzObj = new ObjectWithAuthz(value, authCode);
mapEntry.setValue(authzObj);
if (this.logger.fineEnabled())
this.logger.fine(
"FilterPreAuthorization: putAll: added authorization " + "info for key: " + currkey);
}
// Now each of the map's values have become ObjectWithAuthz
}
return true;
}
@Override
public void close() {}
}