package io.cattle.platform.iaas.api.auth.impl; import io.cattle.platform.api.auth.Identity; import io.cattle.platform.api.auth.impl.DefaultPolicy; import io.cattle.platform.api.auth.impl.PolicyOptions; import io.cattle.platform.core.model.Account; import io.cattle.platform.object.meta.ObjectMetaDataManager; import io.cattle.platform.object.util.ObjectUtils; import io.github.ibuildthecloud.gdapi.context.ApiContext; import io.github.ibuildthecloud.gdapi.factory.SchemaFactory; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class AccountPolicy extends DefaultPolicy { private static final Logger log = LoggerFactory.getLogger(AccountPolicy.class); public AccountPolicy(Account account, Account authenticatedAsAccount, Set<Identity> identities, PolicyOptions options) { super(account.getId(), authenticatedAsAccount.getId(), account.getName(), identities, options); } @Override public <T> T authorizeObject(T obj) { if (hasGrantedAccess(obj)) { return obj; } if (isOption(AUTHORIZED_FOR_ALL_ACCOUNTS) || obj == null) { return obj; } else { if (obj instanceof Account) { if (((Account) obj).getId().longValue() == getAccountId()) { return obj; } else { return null; } } try { Object prop = PropertyUtils.getProperty(obj, ObjectMetaDataManager.ACCOUNT_FIELD); if (prop != null && prop.equals(getAccountId())) { return obj; } else { Object isPublic = ObjectUtils.getPropertyIgnoreErrors(obj, ObjectMetaDataManager.PUBLIC_FIELD); if (isPublic instanceof Boolean && ((Boolean) isPublic).booleanValue()) { return obj; } log.error("Dropping unauthorized object [{}] for acccount [{}]", ObjectUtils.toStringWrapper(obj), getAccountId()); } } catch (IllegalAccessException e) { log.error("Failed to access [{}] field for authorization", ObjectMetaDataManager.ACCOUNT_FIELD, e); return null; } catch (InvocationTargetException e) { log.error("Failed to access [{}] field for authorization", ObjectMetaDataManager.ACCOUNT_FIELD, e); return null; } catch (NoSuchMethodException e) { /* If it doesn't have "accountId," then its authorized */ return obj; } return null; } } @Override public Set<String> getRoles() { SchemaFactory sf = ApiContext.getSchemaFactory(); return sf == null ? Collections.emptySet() : new HashSet<>(Arrays.asList(sf.getId())); } }