package org.ovirt.engine.extensions.aaa.builtin.internal; import java.util.Collection; import java.util.Collections; import java.util.Properties; import org.ovirt.engine.api.extensions.Base; import org.ovirt.engine.api.extensions.ExtKey; import org.ovirt.engine.api.extensions.ExtMap; import org.ovirt.engine.api.extensions.ExtUUID; import org.ovirt.engine.api.extensions.Extension; import org.ovirt.engine.api.extensions.aaa.Authn; import org.ovirt.engine.api.extensions.aaa.Authz; public class InternalAuthz implements Extension { private static final String DEFAULT_PRINCIPAL_NAME = "admin"; private static final String DEFAULT_PRINCIPAL_ID = "fdfc627c-d875-11e0-90f0-83df133b58cc"; private static final String NAMESPACE = "*"; private ExtMap adminUser; private static class Opaque { private boolean firstCall; private boolean found; public Opaque(boolean found) { firstCall = true; this.found = found; } } @Override public void invoke(ExtMap input, ExtMap output) { try { ExtUUID command = input.get(Base.InvokeKeys.COMMAND); if (input.get(Base.InvokeKeys.COMMAND).equals(Base.InvokeCommands.LOAD)) { doLoad(input); } else if (input.get(Base.InvokeKeys.COMMAND).equals(Base.InvokeCommands.INITIALIZE)) { // Do nothing } else if (command.equals(Authz.InvokeCommands.FETCH_PRINCIPAL_RECORD)) { doFetchPrincipalRecord(input, output); } else if (command.equals(Authz.InvokeCommands.QUERY_CLOSE)) { // Do nothing } else if (command.equals(Authz.InvokeCommands.QUERY_OPEN)) { doQueryOpen(input, output); } else if (command.equals(Authz.InvokeCommands.QUERY_EXECUTE)) { doQueryExecute(input, output); } else { output.put( Base.InvokeKeys.RESULT, Base.InvokeResult.UNSUPPORTED ); } output.putIfAbsent(Authz.InvokeKeys.STATUS, Authz.Status.SUCCESS); output.putIfAbsent(Base.InvokeKeys.RESULT, Base.InvokeResult.SUCCESS); } catch (Exception ex) { output.mput( Base.InvokeKeys.RESULT, Base.InvokeResult.FAILED ).mput( Base.InvokeKeys.MESSAGE, ex.getMessage() ); } } private void doQueryOpen(ExtMap input, ExtMap output) { if (input.get(Authz.InvokeKeys.QUERY_ENTITY).equals(Authz.QueryEntity.PRINCIPAL)) { output.put(Authz.InvokeKeys.QUERY_OPAQUE, new Opaque(doQueryOpenImpl(input.get(Authz.InvokeKeys.QUERY_FILTER)))); } else { output.put(Authz.InvokeKeys.QUERY_OPAQUE, new Opaque(false)); } } private boolean doQueryOpenImpl(ExtMap filter) { boolean found = false; if (filter.<Integer> get(Authz.QueryFilterRecord.OPERATOR) == Authz.QueryFilterOperator.EQ) { ExtKey extKey = filter.get(Authz.QueryFilterRecord.KEY); if (extKey.equals(Authz.PrincipalRecord.NAME)) { String name = filter.get(Authz.PrincipalRecord.NAME); found = adminUser.<String>get(Authz.PrincipalRecord.NAME).matches(name.replace("*", ".*")); } else if (extKey.equals(Authz.PrincipalRecord.ID)) { found = filter.<String>get(Authz.PrincipalRecord.ID).equals(adminUser.<String>get(Authz.PrincipalRecord.ID)); } else { found = false; } } else { for (ExtMap currentFilter : filter.<Collection<ExtMap>> get(Authz.QueryFilterRecord.FILTER)) { found = found || doQueryOpenImpl(currentFilter); } } return found; } private void doQueryExecute(ExtMap input, ExtMap output) { Opaque opaque = input.get(Authz.InvokeKeys.QUERY_OPAQUE); output.put(Authz.InvokeKeys.QUERY_RESULT, opaque.firstCall && opaque.found ? Collections.singletonList(adminUser) : null); opaque.firstCall = false; } private void doFetchPrincipalRecord(ExtMap input, ExtMap output) { ExtMap authRecord = input.get(Authn.InvokeKeys.AUTH_RECORD); String principal = authRecord != null ? authRecord.get(Authn.AuthRecord.PRINCIPAL) : input.get(Authz.InvokeKeys.PRINCIPAL); if (principal.equals(adminUser.<String> get(Authz.PrincipalRecord.NAME))) { output.put(Authz.InvokeKeys.PRINCIPAL_RECORD, adminUser); } } private void doLoad(ExtMap input) { ExtMap context = input.get(Base.InvokeKeys.CONTEXT); Properties configuration = context.get(Base.ContextKeys.CONFIGURATION); context.mput( Base.ContextKeys.AUTHOR, "The oVirt Project" ).mput( Base.ContextKeys.EXTENSION_NAME, "Internal Authz (Built-in)" ).mput( Base.ContextKeys.LICENSE, "ASL 2.0" ).mput( Base.ContextKeys.HOME_URL, "http://www.ovirt.org" ).mput( Base.ContextKeys.VERSION, "N/A" ).mput( Authz.ContextKeys.QUERY_MAX_FILTER_SIZE, Integer.parseInt( configuration.getProperty("config.query.filter.size", "10") ) ).mput( Base.ContextKeys.BUILD_INTERFACE_VERSION, Base.INTERFACE_VERSION_CURRENT ).mput( Authz.ContextKeys.AVAILABLE_NAMESPACES, Collections.singletonList(NAMESPACE) ); adminUser = new ExtMap().mput( Authz.PrincipalRecord.NAMESPACE, NAMESPACE ).mput( Authz.PrincipalRecord.NAME, configuration.getProperty("config.authz.user.name", DEFAULT_PRINCIPAL_NAME) ).mput( Authz.PrincipalRecord.FIRST_NAME, configuration.getProperty("config.authz.user.name", DEFAULT_PRINCIPAL_NAME) ).mput( Authz.PrincipalRecord.ID, configuration.getProperty("config.authz.user.id", DEFAULT_PRINCIPAL_ID) ).mput(Authz.PrincipalRecord.PRINCIPAL, configuration.getProperty("config.authz.user.name", DEFAULT_PRINCIPAL_NAME) ); } }