/*
 * Copyright (c) 2013, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Alex Lagarde - initial API and implementation
 */
package org.eclipse.emf.cdo.tests.bugzilla;

import org.eclipse.emf.cdo.CDODeltaNotification;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.security.CDOPermission;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.security.Access;
import org.eclipse.emf.cdo.security.PatternStyle;
import org.eclipse.emf.cdo.security.Realm;
import org.eclipse.emf.cdo.security.Role;
import org.eclipse.emf.cdo.security.SecurityFactory;
import org.eclipse.emf.cdo.security.User;
import org.eclipse.emf.cdo.server.security.ISecurityManager;
import org.eclipse.emf.cdo.server.security.SecurityManagerUtil;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesAfter;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;

import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.security.IPasswordCredentials;
import org.eclipse.net4j.util.security.PasswordCredentials;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.impl.TransactionChangeRecorder;
import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Bug 417483 - [Security] Issues in invalidation when missing write Permission.
 * <p>
 * Tests ensuring that the permissions are correctly computed, no matter what passive update mode is chosen.
 *
 * @author Alex Lagarde
 */
@CleanRepositoriesBefore(reason = "TEST_SECURITY_MANAGER")
@CleanRepositoriesAfter(reason = "TEST_SECURITY_MANAGER")
public class Bugzilla_417483_Test extends AbstractCDOTest
{
  private static final SecurityFactory SF = SecurityFactory.eINSTANCE;

  private static final IPasswordCredentials CREDENTIALS = new PasswordCredentials("Stepper", "12345");

  private static final IPasswordCredentials CREDENTIALS_READ_ONLY = new PasswordCredentials("Lagarde", "54321");

  @Override
  protected void doSetUp() throws Exception
  {
    super.doSetUp();

    ISecurityManager securityManager = SecurityManagerUtil.createSecurityManager("/security", getServerContainer());

    // Start repository
    getTestProperties().put(RepositoryConfig.PROP_TEST_SECURITY_MANAGER, securityManager);
    getRepository();

    securityManager.modify(new ISecurityManager.RealmOperation()
    {
      public void execute(Realm realm)
      {
        User user = realm.addUser(CREDENTIALS);
        user.getRoles().add(realm.getRole("All Objects Writer"));

        User userReadOnly = realm.addUser(CREDENTIALS_READ_ONLY);
        userReadOnly.getRoles().add(realm.getRole("All Objects Reader"));
      }
    });
  }

  public void testPassiveUpdates_Invalidations() throws Exception
  {
    doPassiveUpdates(PassiveUpdateMode.INVALIDATIONS, false);
  }

  public void testPassiveUpdates_InvalidationsWithEditingDomain() throws Exception
  {
    doPassiveUpdates(PassiveUpdateMode.INVALIDATIONS, true);
  }

  public void testPassiveUpdates_Changes() throws Exception
  {
    doPassiveUpdates(PassiveUpdateMode.CHANGES, false);
  }

  public void testPassiveUpdates_Changes_WithEditingDomain() throws Exception
  {
    doPassiveUpdates(PassiveUpdateMode.CHANGES, true);
  }

  public void testPassiveUpdates_Additions() throws Exception
  {
    doPassiveUpdates(PassiveUpdateMode.ADDITIONS, false);
  }

  public void testPassiveUpdates_Additions_WithEditingDomain() throws Exception
  {
    doPassiveUpdates(PassiveUpdateMode.ADDITIONS, true);
  }

  protected void doPassiveUpdates(PassiveUpdateMode passiveUpdateMode, boolean withEditingDomain) throws Exception
  {
    // Both users connect to the repository
    CDOSession session = openSession(CREDENTIALS);
    CDOTransaction transaction = session.openTransaction();

    CDOSession sessionReadOnly = openSession(CREDENTIALS_READ_ONLY);
    sessionReadOnly.options().setPassiveUpdateEnabled(true);
    sessionReadOnly.options().setPassiveUpdateMode(passiveUpdateMode);

    ResourceSet resourceSetReadOnly;
    if (withEditingDomain)
    {
      resourceSetReadOnly = createTransactionalEditingDomain().getResourceSet();
    }
    else
    {
      resourceSetReadOnly = new ResourceSetImpl();
    }

    CDOTransaction transactionReadOnly = sessionReadOnly.openTransaction(resourceSetReadOnly);
    assertEquals(CREDENTIALS.getUserID(), session.getUserID());
    assertEquals(CREDENTIALS_READ_ONLY.getUserID(), sessionReadOnly.getUserID());

    // User with write permission creates a resource and commits
    CDOResource resource = transaction.createResource(getResourcePath("/res"));
    assertEquals(true, isWritable(resource));

    Category category = getModel1Factory().createCategory();
    resource.getContents().add(category);
    commitAndSync(transaction, transactionReadOnly);

    // User without write permission should be able to integrate changes without permission issues
    CDOResource resourceReadOnly = transactionReadOnly.getResource(getResourcePath("/res"));
    assertEquals(1, resourceReadOnly.getContents().size());
    assertEquals("User should not have write permission on resource", false, isWritable(resourceReadOnly));

    // => Trigger loading of resource root so that invalidation are sent
    Category categoryReadOnly = (Category)resourceReadOnly.getContents().get(0);
    assertEquals("User should not have write permission on element", false, isWritable(categoryReadOnly));

    // User with write permission modifies the resource root and commits
    category.getProducts().add(getModel1Factory().createProduct1());
    category.setName("RENAMED");

    final CountDownLatch latch = new CountDownLatch(1);
    transactionReadOnly.addListener(new IListener()
    {
      public void notifyEvent(IEvent event)
      {
        if (event instanceof CDOViewInvalidationEvent)
        {
          latch.countDown();
        }
      }
    });

    transaction.commit();

    // User without write permission should be able to integrate changes without permission issues
    boolean notified = latch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
    assertEquals("Timeout: User should have been notified of changes", true, notified);

    assertEquals("User should not have write permission on resource", false, isWritable(resourceReadOnly));
    assertEquals("User should not have write permission on element", false, isWritable(categoryReadOnly));
  }

  /**
   * Creates a {@link TransactionalEditingDomain} which has a {@link TransactionChangeRecorder} that does not throw an {@link IllegalStateException} if model is modified through a {@link CDODeltaNotification}.
   */
  private TransactionalEditingDomain createTransactionalEditingDomain()
  {
    return new TransactionalEditingDomainImpl(null)
    {
      @Override
      protected TransactionChangeRecorder createChangeRecorder(ResourceSet rset)
      {
        return new TransactionChangeRecorder(this, rset)
        {
          @Override
          public void notifyChanged(Notification notification)
          {
            if (!(notification instanceof CDODeltaNotification))
            {
              super.notifyChanged(notification);
            }
          }
        };
      }
    };
  }

  public void testLoad_NoPermission() throws Exception
  {
    final IPasswordCredentials credentials = new PasswordCredentials("user", "password");
    final String protectedResource = getResourcePath("/protected");

    getSecurityManager().modify(new ISecurityManager.RealmOperation()
    {
      public void execute(Realm realm)
      {
        User user = realm.addUser(credentials);

        Role role = realm.addRole(protectedResource + " Reader");
        role.getPermissions().add(SF.createFilterPermission(Access.READ, //
            SF.createResourceFilter(protectedResource, PatternStyle.EXACT, true).setModelObjects(false)));

        user.getRoles().add(role);
      }
    });

    {
      // Init model with write full access
      CDOSession session = openSession(CREDENTIALS);
      CDOTransaction transaction = session.openTransaction();
      CDOResource resource = transaction.createResource(protectedResource);
      resource.getContents().add(getModel1Factory().createCompany());
      transaction.commit();
      session.close();
    }

    CDOSession session = openSession(credentials);
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.getResource(protectedResource);
    assertEquals(CDOPermission.READ, resource.cdoPermission());

    Company company = (Company)resource.getContents().get(0);
    assertEquals(CDOPermission.NONE, CDOUtil.getCDOObject(company).cdoPermission());
  }

  public void testLoad_ReadPermission() throws Exception
  {
    final IPasswordCredentials credentials = new PasswordCredentials("user", "password");
    final String protectedResource = getResourcePath("/protected");

    getSecurityManager().modify(new ISecurityManager.RealmOperation()
    {
      public void execute(Realm realm)
      {
        User user = realm.addUser(credentials);

        Role role = realm.addRole(protectedResource + " Reader");
        role.getPermissions().add(SF.createFilterPermission(Access.READ, //
            SF.createResourceFilter(protectedResource, PatternStyle.TREE, true)));

        user.getRoles().add(role);
      }
    });

    {
      // Init model with write full access
      CDOSession session = openSession(CREDENTIALS);
      CDOTransaction transaction = session.openTransaction();
      CDOResource resource = transaction.createResource(protectedResource);
      resource.getContents().add(getModel1Factory().createCompany());
      transaction.commit();
      session.close();
    }

    CDOSession session = openSession(credentials);
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.getResource(protectedResource);
    assertEquals(CDOPermission.READ, resource.cdoPermission());

    Company company = (Company)resource.getContents().get(0);
    assertEquals(CDOPermission.READ, CDOUtil.getCDOObject(company).cdoPermission());
  }

  public void testCommit_NoPermission() throws Exception
  {
    final IPasswordCredentials credentials = new PasswordCredentials("user", "password");
    final String protectedResource = getResourcePath("/protected");

    getSecurityManager().modify(new ISecurityManager.RealmOperation()
    {
      public void execute(Realm realm)
      {
        User user = realm.addUser(credentials);

        Role role = realm.addRole(protectedResource + " Writer");
        role.getPermissions().add(SF.createFilterPermission(Access.WRITE, //
            SF.createResourceFilter(protectedResource, PatternStyle.EXACT, true).setModelObjects(false)));

        user.getRoles().add(role);
      }
    });

    CDOSession session = openSession(credentials);
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.createResource(protectedResource);
    assertEquals(CDOPermission.WRITE, resource.cdoPermission());

    Company company = getModel1Factory().createCompany();
    resource.getContents().add(company);
    assertEquals(CDOPermission.WRITE, CDOUtil.getCDOObject(company).cdoPermission());

    transaction.commit();
    assertEquals(CDOPermission.NONE, CDOUtil.getCDOObject(company).cdoPermission());
  }

  public void testCommit_ReadPermission() throws Exception
  {
    final IPasswordCredentials credentials = new PasswordCredentials("user", "password");
    final String protectedResource = getResourcePath("/protected");

    getSecurityManager().modify(new ISecurityManager.RealmOperation()
    {
      public void execute(Realm realm)
      {
        User user = realm.addUser(credentials);

        Role role = realm.addRole(protectedResource + " Writer");
        role.getPermissions().add(SF.createFilterPermission(Access.WRITE, //
            SF.createResourceFilter(protectedResource, PatternStyle.EXACT, true).setModelObjects(false)));
        role.getPermissions().add(SF.createFilterPermission(Access.READ, //
            SF.createResourceFilter(protectedResource, PatternStyle.EXACT, false).setModelObjects(true)));

        user.getRoles().add(role);
      }
    });

    CDOSession session = openSession(credentials);
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.createResource(protectedResource);
    assertEquals(CDOPermission.WRITE, resource.cdoPermission());

    Company company = getModel1Factory().createCompany();
    resource.getContents().add(company);
    assertEquals(CDOPermission.WRITE, CDOUtil.getCDOObject(company).cdoPermission());

    transaction.commit();
    assertEquals(CDOPermission.READ, CDOUtil.getCDOObject(company).cdoPermission());
  }

  public void testCommit_WritePermission() throws Exception
  {
    final IPasswordCredentials credentials = new PasswordCredentials("user", "password");
    final String protectedResource = getResourcePath("/protected");

    getSecurityManager().modify(new ISecurityManager.RealmOperation()
    {
      public void execute(Realm realm)
      {
        User user = realm.addUser(credentials);

        Role role = realm.addRole(protectedResource + " Writer");
        role.getPermissions().add(SF.createFilterPermission(Access.WRITE, //
            SF.createResourceFilter(protectedResource, PatternStyle.EXACT, true).setModelObjects(true)));

        user.getRoles().add(role);
      }
    });

    CDOSession session = openSession(credentials);
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.createResource(protectedResource);
    assertEquals(CDOPermission.WRITE, resource.cdoPermission());

    Company company = getModel1Factory().createCompany();
    resource.getContents().add(company);
    assertEquals(CDOPermission.WRITE, CDOUtil.getCDOObject(company).cdoPermission());

    transaction.commit();
    assertEquals(CDOPermission.WRITE, CDOUtil.getCDOObject(company).cdoPermission());
  }

  private ISecurityManager getSecurityManager()
  {
    InternalRepository repository = getRepository();
    return SecurityManagerUtil.getSecurityManager(repository);
  }

  private boolean isWritable(EObject object)
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDORevision revision = cdoObject.cdoRevision(true);
    return revision.isWritable();
  }
}
