/*
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.hadoop.ozone.recon.api.filters;

import com.google.common.collect.Sets;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.recon.ReconConfigKeys;
import org.apache.hadoop.ozone.OzoneConfigKeys;
import org.apache.hadoop.ozone.recon.api.AdminOnly;
import org.apache.hadoop.ozone.recon.api.ClusterStateEndpoint;
import org.apache.hadoop.ozone.recon.api.MetricsProxyEndpoint;
import org.apache.hadoop.ozone.recon.api.NodeEndpoint;
import org.apache.hadoop.ozone.recon.api.PipelineEndpoint;
import org.apache.hadoop.ozone.recon.api.TaskStatusService;
import org.apache.hadoop.ozone.recon.api.UtilizationEndpoint;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Path;
import java.security.Principal;
import java.util.HashSet;
import java.util.Set;

/**
 * Tests the admin filter on recon endpoints which should only be accessible
 * to admins.
 */
public class TestAdminFilter {
  /**
   * Tests that only designated endpoints are not marked with the @AdminOnly
   * annotation, meaning they are accessible to all users.
   */
  @Test
  public void testAdminOnlyEndpoints() {
    // Get all classes with @Path annotation anywhere in recon.
    Reflections reflections = new Reflections(
        "org.apache.hadoop.ozone.recon",
        new TypeAnnotationsScanner(),
        new SubTypesScanner());
    Set<Class<?>> allEndpoints =
        reflections.getTypesAnnotatedWith(Path.class);

    Assertions.assertFalse(allEndpoints.isEmpty());

    // If an endpoint is added, it must be explicitly added to this set or be
    // marked with @AdminOnly for this test to pass.
    Set<Class<?>> nonAdminEndpoints = new HashSet<>();
    nonAdminEndpoints.add(UtilizationEndpoint.class);
    nonAdminEndpoints.add(ClusterStateEndpoint.class);
    nonAdminEndpoints.add(MetricsProxyEndpoint.class);
    nonAdminEndpoints.add(NodeEndpoint.class);
    nonAdminEndpoints.add(PipelineEndpoint.class);
    nonAdminEndpoints.add(TaskStatusService.class);

    Assertions.assertTrue(allEndpoints.containsAll(nonAdminEndpoints));

    Set<Class<?>> adminEndpoints = Sets.difference(allEndpoints,
        nonAdminEndpoints);

    for (Class<?> endpoint: nonAdminEndpoints) {
      Assertions.assertFalse(endpoint.isAnnotationPresent(AdminOnly.class),
          String.format("Endpoint class %s has been declared as non admin " +
              "in this test, but is marked as @AdminOnly.", endpoint));
    }

    for (Class<?> endpoint: adminEndpoints) {
      Assertions.assertTrue(endpoint.isAnnotationPresent(AdminOnly.class),
          String.format("Endpoint class %s must be marked as @AdminOnly " +
              "or explicitly declared as non admin in this test.", endpoint));
    }
  }

  @Test
  public void testAdminFilterOzoneAdminsOnly() throws Exception {
    OzoneConfiguration conf = new OzoneConfiguration();
    conf.setStrings(OzoneConfigKeys.OZONE_ADMINISTRATORS, "ozone");
    testAdminFilterWithPrincipal(conf, "ozone", true);
    testAdminFilterWithPrincipal(conf, "reject", false);

    conf.setStrings(OzoneConfigKeys.OZONE_ADMINISTRATORS,
        OzoneConfigKeys.OZONE_ADMINISTRATORS_WILDCARD);
    testAdminFilterWithPrincipal(conf, "other", true);
  }

  @Test
  public void testAdminFilterReconAdminsOnly() throws Exception {
    OzoneConfiguration conf = new OzoneConfiguration();
    conf.setStrings(ReconConfigKeys.OZONE_RECON_ADMINISTRATORS, "recon");
    testAdminFilterWithPrincipal(conf, "recon", true);
    testAdminFilterWithPrincipal(conf, "reject", false);

    conf.setStrings(ReconConfigKeys.OZONE_RECON_ADMINISTRATORS,
        OzoneConfigKeys.OZONE_ADMINISTRATORS_WILDCARD);
    testAdminFilterWithPrincipal(conf, "other", true);
  }

  @Test
  public void testAdminFilterOzoneAndReconAdmins() throws Exception {
    OzoneConfiguration conf = new OzoneConfiguration();
    conf.setStrings(OzoneConfigKeys.OZONE_ADMINISTRATORS, "ozone");
    conf.setStrings(ReconConfigKeys.OZONE_RECON_ADMINISTRATORS, "recon");
    testAdminFilterWithPrincipal(conf, "ozone", true);
    testAdminFilterWithPrincipal(conf, "recon", true);
    testAdminFilterWithPrincipal(conf, "reject", false);

    conf.setStrings(OzoneConfigKeys.OZONE_ADMINISTRATORS,
        OzoneConfigKeys.OZONE_ADMINISTRATORS_WILDCARD);
    conf.setStrings(ReconConfigKeys.OZONE_RECON_ADMINISTRATORS,
        OzoneConfigKeys.OZONE_ADMINISTRATORS_WILDCARD);
    testAdminFilterWithPrincipal(conf, "other", true);
  }

  @Test
  public void testAdminFilterNoAdmins() throws Exception {
    testAdminFilterWithPrincipal(new OzoneConfiguration(), "reject", false);
  }

  private void testAdminFilterWithPrincipal(OzoneConfiguration conf,
      String principalToUse, boolean shouldPass) throws Exception {
    Principal mockPrincipal = Mockito.mock(Principal.class);
    Mockito.when(mockPrincipal.getName()).thenReturn(principalToUse);
    HttpServletRequest mockRequest = Mockito.mock(HttpServletRequest.class);
    Mockito.when(mockRequest.getUserPrincipal()).thenReturn(mockPrincipal);

    HttpServletResponse mockResponse = Mockito.mock(HttpServletResponse.class);
    FilterChain mockFilterChain = Mockito.mock(FilterChain.class);

    new ReconAdminFilter(conf).doFilter(mockRequest, mockResponse,
        mockFilterChain);

    if (shouldPass) {
      Mockito.verify(mockFilterChain).doFilter(mockRequest, mockResponse);
    } else {
      Mockito.verify(mockResponse).setStatus(HttpServletResponse.SC_FORBIDDEN);
    }
  }
}
