/*
 * 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 org.apache.nifi.registry.security.authorization.resource;

import org.apache.nifi.registry.security.authorization.AuthorizationAuditor;
import org.apache.nifi.registry.security.authorization.AuthorizationRequest;
import org.apache.nifi.registry.security.authorization.AuthorizationResult;
import org.apache.nifi.registry.security.authorization.AuthorizationResult.Result;
import org.apache.nifi.registry.security.authorization.Authorizer;
import org.apache.nifi.registry.security.authorization.RequestAction;
import org.apache.nifi.registry.security.authorization.Resource;
import org.apache.nifi.registry.security.authorization.UserContextKeys;
import org.apache.nifi.registry.security.authorization.exception.AccessDeniedException;
import org.apache.nifi.registry.security.authorization.user.NiFiUser;

import java.util.HashMap;
import java.util.Map;

public interface Authorizable {

    /**
     * The parent for this Authorizable. May be null.
     *
     * @return the parent authorizable or null
     */
    Authorizable getParentAuthorizable();

    /**
     * The Resource for this Authorizable.
     *
     * @return the resource
     */
    Resource getResource();

    /**
     * The originally requested resource for this Authorizable. Because policies are inherited, if a resource
     * does not have a policy, this Authorizable may represent a parent resource and this method will return
     * the originally requested resource.
     *
     * @return the originally requested resource
     */
    default Resource getRequestedResource() {
        return getResource();
    }

    /**
     * Returns whether the current user is authorized for the specified action on the specified resource. This
     * method does not imply the user is directly attempting to access the specified resource. If the user is
     * attempting a direct access use Authorizable.authorize().
     *
     * @param authorizer authorizer
     * @param action action
     * @return is authorized
     */
    default boolean isAuthorized(Authorizer authorizer, RequestAction action, NiFiUser user) {
        return Result.Approved.equals(checkAuthorization(authorizer, action, user).getResult());
    }

    /**
     * Returns the result of an authorization request for the specified user for the specified action on the specified
     * resource. This method does not imply the user is directly attempting to access the specified resource. If the user is
     * attempting a direct access use Authorizable.authorize().
     *
     * @param authorizer authorizer
     * @param action action
     * @param user user
     * @return is authorized
     */
    default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
        if (user == null) {
            return AuthorizationResult.denied("Unknown user.");
        }

        final Map<String,String> userContext;
        if (user.getClientAddress() != null && !user.getClientAddress().trim().isEmpty()) {
            userContext = new HashMap<>();
            userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress());
        } else {
            userContext = null;
        }

        final Resource resource = getResource();
        final Resource requestedResource = getRequestedResource();
        final AuthorizationRequest request = new AuthorizationRequest.Builder()
                .identity(user.getIdentity())
                .groups(user.getGroups())
                .anonymous(user.isAnonymous())
                .accessAttempt(false)
                .action(action)
                .resource(resource)
                .requestedResource(requestedResource)
                .resourceContext(resourceContext)
                .userContext(userContext)
                .explanationSupplier(() -> {
                    // build the safe explanation
                    final StringBuilder safeDescription = new StringBuilder("Unable to ");

                    if (RequestAction.READ.equals(action)) {
                        safeDescription.append("view ");
                    } else {
                        safeDescription.append("modify "); // covers write or delete
                    }
                    safeDescription.append(resource.getSafeDescription()).append(".");

                    return safeDescription.toString();
                })
                .build();

        // perform the authorization
        final AuthorizationResult result = authorizer.authorize(request);

        // verify the results
        if (Result.ResourceNotFound.equals(result.getResult())) {
            final Authorizable parent = getParentAuthorizable();
            if (parent == null) {
                return AuthorizationResult.denied("No applicable policies could be found.");
            } else {
                // create a custom authorizable to override the safe description but still defer to the parent authorizable
                final Authorizable parentProxy = new Authorizable() {
                    @Override
                    public Authorizable getParentAuthorizable() {
                        return parent.getParentAuthorizable();
                    }

                    @Override
                    public Resource getRequestedResource() {
                        return requestedResource;
                    }

                    @Override
                    public Resource getResource() {
                        final Resource parentResource = parent.getResource();
                        return new Resource() {
                            @Override
                            public String getIdentifier() {
                                return parentResource.getIdentifier();
                            }

                            @Override
                            public String getName() {
                                return parentResource.getName();
                            }

                            @Override
                            public String getSafeDescription() {
                                return resource.getSafeDescription();
                            }
                        };
                    }
                };
                return parentProxy.checkAuthorization(authorizer, action, user, resourceContext);
            }
        } else {
            return result;
        }
    }

    /**
     * Returns the result of an authorization request for the specified user for the specified action on the specified
     * resource. This method does not imply the user is directly attempting to access the specified resource. If the user is
     * attempting a direct access use Authorizable.authorize().
     *
     * @param authorizer authorizer
     * @param action action
     * @param user user
     * @return is authorized
     */
    default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user) {
        return checkAuthorization(authorizer, action, user, null);
    }

    /**
     * Authorizes the current user for the specified action on the specified resource. This method does imply the user is
     * directly accessing the specified resource.
     *
     * @param authorizer authorizer
     * @param action action
     * @param user user
     * @param resourceContext resource context
     */
    default void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException {
        if (user == null) {
            throw new AccessDeniedException("Unknown user.");
        }

        final Map<String,String> userContext;
        if (user.getClientAddress() != null && !user.getClientAddress().trim().isEmpty()) {
            userContext = new HashMap<>();
            userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress());
        } else {
            userContext = null;
        }

        final Resource resource = getResource();
        final Resource requestedResource = getRequestedResource();
        final AuthorizationRequest request = new AuthorizationRequest.Builder()
                .identity(user.getIdentity())
                .groups(user.getGroups())
                .anonymous(user.isAnonymous())
                .accessAttempt(true)
                .action(action)
                .resource(resource)
                .requestedResource(requestedResource)
                .resourceContext(resourceContext)
                .userContext(userContext)
                .explanationSupplier(() -> {
                    // build the safe explanation
                    final StringBuilder safeDescription = new StringBuilder("Unable to ");

                    if (RequestAction.READ.equals(action)) {
                        safeDescription.append("view ");
                    } else {
                        safeDescription.append("modify ");
                    }
                    safeDescription.append(resource.getSafeDescription()).append(".");

                    return safeDescription.toString();
                })
                .build();

        final AuthorizationResult result = authorizer.authorize(request);
        if (Result.ResourceNotFound.equals(result.getResult())) {
            final Authorizable parent = getParentAuthorizable();
            if (parent == null) {
                final AuthorizationResult failure = AuthorizationResult.denied("No applicable policies could be found.");

                // audit authorization request
                if (authorizer instanceof AuthorizationAuditor) {
                    ((AuthorizationAuditor) authorizer).auditAccessAttempt(request, failure);
                }

                // denied
                throw new AccessDeniedException(failure.getExplanation());
            } else {
                // create a custom authorizable to override the safe description but still defer to the parent authorizable
                final Authorizable parentProxy = new Authorizable() {
                    @Override
                    public Authorizable getParentAuthorizable() {
                        return parent.getParentAuthorizable();
                    }

                    @Override
                    public Resource getRequestedResource() {
                        return requestedResource;
                    }

                    @Override
                    public Resource getResource() {
                        final Resource parentResource = parent.getResource();
                        return new Resource() {
                            @Override
                            public String getIdentifier() {
                                return parentResource.getIdentifier();
                            }

                            @Override
                            public String getName() {
                                return parentResource.getName();
                            }

                            @Override
                            public String getSafeDescription() {
                                return resource.getSafeDescription();
                            }
                        };
                    }
                };
                parentProxy.authorize(authorizer, action, user, resourceContext);
            }
        } else if (Result.Denied.equals(result.getResult())) {
            throw new AccessDeniedException(result.getExplanation());
        }
    }

    /**
     * Authorizes the current user for the specified action on the specified resource. This method does imply the user is
     * directly accessing the specified resource.
     *
     * @param authorizer authorizer
     * @param action action
     * @param user user
     */
    default void authorize(Authorizer authorizer, RequestAction action, NiFiUser user) throws AccessDeniedException {
        authorize(authorizer, action, user, null);
    }
}
