// 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 com.cloud.acl;

import javax.ejb.Local;

import com.cloud.api.BaseCmd;
import com.cloud.dc.DataCenter;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.network.Network;
import com.cloud.network.NetworkManager;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.projects.ProjectManager;
import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.dao.LaunchPermissionDao;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;

@Local(value=SecurityChecker.class)
public class DomainChecker extends AdapterBase implements SecurityChecker {
    
    @Inject DomainDao _domainDao;
    @Inject AccountDao _accountDao;
    @Inject LaunchPermissionDao _launchPermissionDao;
    @Inject ProjectManager _projectMgr;
    @Inject ProjectAccountDao _projecAccountDao;
    @Inject NetworkManager _networkMgr;
    
    protected DomainChecker() {
        super();
    }
    
    @Override
    public boolean checkAccess(Account caller, Domain domain) throws PermissionDeniedException {
        if (caller.getState() != Account.State.enabled) {
            throw new PermissionDeniedException(caller + " is disabled.");
        }
        long domainId = domain.getId();
        
        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
            if (caller.getDomainId() != domainId) {
                throw new PermissionDeniedException(caller + " does not have permission to operate within domain id=" + domain.getId());
            }
        } else if (!_domainDao.isChildDomain(caller.getDomainId(), domainId)) {
            throw new PermissionDeniedException(caller + " does not have permission to operate within domain id=" + domain.getId());
        }
        
        return true;
    }

    @Override
    public boolean checkAccess(User user, Domain domain) throws PermissionDeniedException {
        if (user.getRemoved() != null) {
            throw new PermissionDeniedException(user + " is no longer active.");
        }
        Account account = _accountDao.findById(user.getAccountId());
        return checkAccess(account, domain);
    }

    @Override
    public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType) throws PermissionDeniedException {
        if (entity instanceof VirtualMachineTemplate) {
            
            VirtualMachineTemplate template = (VirtualMachineTemplate)entity;
            Account owner = _accountDao.findById(template.getAccountId());
            // validate that the template is usable by the account
            if (!template.isPublicTemplate()) {
                if (BaseCmd.isRootAdmin(caller.getType()) || (owner.getId() == caller.getId())) {
                    return true;
                }
                
                // since the current account is not the owner of the template, check the launch permissions table to see if the
                // account can launch a VM from this template
                LaunchPermissionVO permission = _launchPermissionDao.findByTemplateAndAccount(template.getId(), caller.getId());
                if (permission == null) {
                    throw new PermissionDeniedException(caller + " does not have permission to launch instances from " + template);
                }
            } else {
                // Domain admin and regular user can delete/modify only templates created by them
                if (accessType != null && accessType == AccessType.ModifyEntry) {
                    if (!BaseCmd.isRootAdmin(caller.getType()) && owner.getId() != caller.getId()) {
                        throw new PermissionDeniedException("Domain Admin and regular users can modify only their own Public templates");
                    }
                }
            }
            
            return true;
        } else if (entity instanceof Network && accessType != null && accessType == AccessType.UseNetwork) {
        	_networkMgr.checkNetworkPermissions(caller, (Network)entity);
        } else {
            if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
                Account account = _accountDao.findById(entity.getAccountId());
                
                if (account != null && account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
                    //only project owner can delete/modify the project
                    if (accessType != null && accessType == AccessType.ModifyProject) {
                        if (!_projectMgr.canModifyProjectAccount(caller, account.getId())) {
                            throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
                        }
                    } else if (!_projectMgr.canAccessProjectAccount(caller, account.getId())){
                        throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
                    }
                } else {
                    if (caller.getId() != entity.getAccountId()) {
                        throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
                    }
                }  
            }
        }
        
        return true;
    }

    @Override
    public boolean checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
        Account account = _accountDao.findById(user.getAccountId());
        return checkAccess(account, entity, null);
    }

	@Override
	public boolean checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException 
	{
		if(account == null || dof.getDomainId() == null)
		{//public offering
			return true;
		}
		else
		{
			//admin has all permissions
			if(account.getType() == Account.ACCOUNT_TYPE_ADMIN)
			{
				return true;
			}		
			//if account is normal user or domain admin
			//check if account's domain is a child of zone's domain (Note: This is made consistent with the list command for disk offering)
			else if(account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN || account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
			{
				if(account.getDomainId() == dof.getDomainId())
				{
					return true; //disk offering and account at exact node
				}
				else
				{
		    		DomainVO domainRecord = _domainDao.findById(account.getDomainId());
		    		if(domainRecord != null)
		    		{
		    			while(true)
		    			{
		    				if(domainRecord.getId() == dof.getDomainId())
		    				{
		    					//found as a child
		    					return true;
		    				}
		    				if(domainRecord.getParent() != null) {
                                domainRecord = _domainDao.findById(domainRecord.getParent());
                            } else {
                                break;
                            }
		    			}
		    		}
				}
			}
		}
		//not found
		return false;
	}	

	@Override
	public boolean checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException 
	{
		if(account == null || so.getDomainId() == null)
		{//public offering
			return true;
		}
		else
		{
			//admin has all permissions
			if(account.getType() == Account.ACCOUNT_TYPE_ADMIN)
			{
				return true;
			}		
			//if account is normal user or domain admin
			//check if account's domain is a child of zone's domain (Note: This is made consistent with the list command for service offering)
			else if(account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN || account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
			{
				if(account.getDomainId() == so.getDomainId())
				{
					return true; //service offering and account at exact node
				}
				else
				{
		    		DomainVO domainRecord = _domainDao.findById(account.getDomainId());
		    		if(domainRecord != null)
		    		{
		    			while(true)
		    			{
		    				if(domainRecord.getId() == so.getDomainId())
		    				{
		    					//found as a child
		    					return true;
		    				}
		    				if(domainRecord.getParent() != null) {
                                domainRecord = _domainDao.findById(domainRecord.getParent());
                            } else {
                                break;
                            }
		    			}
		    		}
				}
			}
		}
		//not found
		return false;
	}	
    
	@Override
	public boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException {
		if(account == null || zone.getDomainId() == null){//public zone
			return true;
		}else{
			//admin has all permissions
			if(account.getType() == Account.ACCOUNT_TYPE_ADMIN){
				return true;
			}		
			//if account is normal user
			//check if account's domain is a child of zone's domain
			else if(account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_PROJECT){
				if(account.getDomainId() == zone.getDomainId()){
					return true; //zone and account at exact node
				}else{
		    		DomainVO domainRecord = _domainDao.findById(account.getDomainId());
		    		if(domainRecord != null)
		    		{
		    			while(true){
		    				if(domainRecord.getId() == zone.getDomainId()){
		    					//found as a child
		    					return true;
		    				}
		    				if(domainRecord.getParent() != null) {
                                domainRecord = _domainDao.findById(domainRecord.getParent());
                            } else {
                                break;
                            }
		    			}
		    		}
				}
				//not found
				return false;
			}
			//if account is domain admin
			//check if the account's domain is either child of zone's domain, or if zone's domain is child of account's domain
			else if(account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN){
				if(account.getDomainId() == zone.getDomainId()){
					return true; //zone and account at exact node
				}else{
					DomainVO zoneDomainRecord = _domainDao.findById(zone.getDomainId());
		    		DomainVO accountDomainRecord = _domainDao.findById(account.getDomainId());
		    		if(accountDomainRecord != null)
		    		{
		    			DomainVO localRecord = accountDomainRecord;
		    			while(true){
		    				if(localRecord.getId() == zone.getDomainId()){
		    					//found as a child
		    					return true;
		    				}
		    				if(localRecord.getParent() != null) {
                                localRecord = _domainDao.findById(localRecord.getParent());
                            } else {
                                break;
                            }
		    			}
		    		}
		    		//didn't find in upper tree
		    		if(zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())){
		    			return true;
		    		}
				}
				//not found
				return false;
			}
		}
		return false;
	}
}
