Package com.orientechnologies.orient.core.metadata.security

Source Code of com.orientechnologies.orient.core.metadata.security.ORestrictedAccessHook

/*
  *
  *  *  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.core.metadata.security;

import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.record.ODatabaseRecord;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.exception.OConfigurationException;
import com.orientechnologies.orient.core.exception.OSecurityException;
import com.orientechnologies.orient.core.hook.ODocumentHookAbstract;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OClassImpl;
import com.orientechnologies.orient.core.record.impl.ODocument;

import java.util.Set;

/**
* Checks the access against restricted resources. Restricted resources are those documents of classes that implement ORestricted
* abstract class.
*
* @author Luca Garulli
*/
public class ORestrictedAccessHook extends ODocumentHookAbstract {
  public ORestrictedAccessHook() {
  }

  public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() {
    return DISTRIBUTED_EXECUTION_MODE.BOTH;
  }

  @Override
  public RESULT onRecordBeforeCreate(final ODocument iDocument) {
    final OClass cls = iDocument.getSchemaClass();
    if (cls != null && cls.isSubClassOf(OSecurityShared.RESTRICTED_CLASSNAME)) {
      String fieldNames = ((OClassImpl) cls).getCustom(OSecurityShared.ONCREATE_FIELD);
      if (fieldNames == null)
        fieldNames = OSecurityShared.ALLOW_ALL_FIELD;
      final String[] fields = fieldNames.split(",");
      String identityType = ((OClassImpl) cls).getCustom(OSecurityShared.ONCREATE_IDENTITY_TYPE);
      if (identityType == null)
        identityType = "user";

      final ODatabaseRecord db = ODatabaseRecordThreadLocal.INSTANCE.get();

      ODocument identity = null;
      if (identityType.equals("user")) {
        final OUser user = db.getUser();
        if (user != null)
          identity = user.getDocument();
      } else if (identityType.equals("role")) {
        final Set<ORole> roles = db.getUser().getRoles();
        if (!roles.isEmpty())
          identity = roles.iterator().next().getDocument();
      } else
        throw new OConfigurationException("Wrong custom field '" + OSecurityShared.ONCREATE_IDENTITY_TYPE + "' in class '"
            + cls.getName() + "' with value '" + identityType + "'. Supported ones are: 'user', 'role'");

      if (identity != null) {
        for (String f : fields)
          db.getMetadata().getSecurity().allowIdentity(iDocument, f, identity);
        return RESULT.RECORD_CHANGED;
      }
    }
    return RESULT.RECORD_NOT_CHANGED;
  }

  @Override
  public RESULT onRecordBeforeRead(final ODocument iDocument) {
    return isAllowed(iDocument, OSecurityShared.ALLOW_READ_FIELD, false) ? RESULT.RECORD_NOT_CHANGED : RESULT.SKIP;
  }

  @Override
  public RESULT onRecordBeforeUpdate(final ODocument iDocument) {
    if (!isAllowed(iDocument, OSecurityShared.ALLOW_UPDATE_FIELD, true))
      throw new OSecurityException("Cannot update record " + iDocument.getIdentity() + ": the resource has restricted access");
    return RESULT.RECORD_NOT_CHANGED;
  }

  @Override
  public RESULT onRecordBeforeDelete(final ODocument iDocument) {
    if (!isAllowed(iDocument, OSecurityShared.ALLOW_DELETE_FIELD, true))
      throw new OSecurityException("Cannot delete record " + iDocument.getIdentity() + ": the resource has restricted access");
    return RESULT.RECORD_NOT_CHANGED;
  }

  @SuppressWarnings("unchecked")
  protected boolean isAllowed(final ODocument iDocument, final String iAllowOperation, final boolean iReadOriginal) {
    final OClass cls = iDocument.getSchemaClass();
    if (cls != null && cls.isSubClassOf(OSecurityShared.RESTRICTED_CLASSNAME)) {

      final ODatabaseRecord db = ODatabaseRecordThreadLocal.INSTANCE.get();

      if (db.getUser() == null)
        return true;

      if (db.getUser().isRuleDefined(ODatabaseSecurityResources.BYPASS_RESTRICTED))
        if (db.getUser().checkIfAllowed(ODatabaseSecurityResources.BYPASS_RESTRICTED, ORole.PERMISSION_READ) != null)
          // BYPASS RECORD LEVEL SECURITY: ONLY "ADMIN" ROLE CAN BY DEFAULT
          return true;

      final ODocument doc;
      if (iReadOriginal)
        // RELOAD TO AVOID HACKING OF "_ALLOW" FIELDS
        doc = (ODocument) db.load(iDocument.getIdentity());
      else
        doc = iDocument;

      return db
          .getMetadata()
          .getSecurity()
          .isAllowed((Set<OIdentifiable>) doc.field(OSecurityShared.ALLOW_ALL_FIELD),
              (Set<OIdentifiable>) doc.field(iAllowOperation));
    }

    return true;
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.metadata.security.ORestrictedAccessHook

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.