/** Creates VOUserDetails with given key, userId, orgId. */
 private VOUserDetails createVOUserDetails(long key, String id, String orgId) {
   VOUserDetails user = new VOUserDetails();
   user.setUserId(id);
   user.setKey(key);
   user.setOrganizationId(orgId);
   return user;
 }
  @SuppressWarnings("unchecked")
  @Test
  public void testAuthenticateTMForController_noControllerSettings() throws Throwable {

    // given
    VOUserDetails manager = createVOUserDetails(10000, "user", "tp123");
    Mockito.doThrow(new ConfigurationException("test"))
        .when(configService)
        .getAuthenticationForBESTechnologyManager(
            Matchers.anyString(), Matchers.any(ServiceInstance.class), Matchers.anyMap());
    Mockito.doReturn(null)
        .when(authService)
        .getAuthenticatedTMForController(
            Matchers.anyString(), Matchers.any(PasswordAuthentication.class));
    ArgumentCaptor<PasswordAuthentication> ac =
        ArgumentCaptor.forClass(PasswordAuthentication.class);

    // when
    authenticateTMForController(CTRL_ID, manager.getUserId(), "pass");

    // then
    Mockito.verify(authService).getAuthenticatedTMForController(Matchers.anyString(), ac.capture());
    assertEquals(manager.getUserId(), ac.getValue().getUserName());
    assertEquals("pass", ac.getValue().getPassword());
  }
  @SuppressWarnings("unchecked")
  @Test
  public void testAuthenticateAdministrator_SSO() throws Throwable {
    // given
    Map<String, String> settings = getProxySettingsForMode("SAML_SP");
    VOUserDetails admin = createVOUserDetails(1000, "admin", "org");
    admin.setUserRoles(Collections.singleton(UserRoleType.ORGANIZATION_ADMIN));

    Mockito.doReturn(admin)
        .when(besDAO)
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());
    Mockito.doReturn(new PasswordAuthentication("nobody", ""))
        .when(configService)
        .getWebServiceAuthentication(Matchers.any(ServiceInstance.class), Matchers.anyMap());
    Mockito.doReturn(settings).when(configService).getAllProxyConfigurationSettings();

    // when
    authService.authenticateAdministrator(
        new PasswordAuthentication(admin.getUserId(), "admin123"));

    // then
    Mockito.verify(besDAO, Mockito.times(0))
        .getUser(Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class));
  }
  @Test
  public void testAuthenticateTMForController_SSO() throws Throwable {

    // given
    Map<String, String> proxySettings = getProxySettingsForMode("SAML_SP");
    Map<String, Setting> controlleSettings = getControllerSettingsForOrg("tp123");

    VOUserDetails manager = createVOUserDetails(10001, "user", "tp123");
    manager.setUserRoles(Collections.singleton(UserRoleType.TECHNOLOGY_MANAGER));

    Mockito.doReturn(proxySettings).when(configService).getAllProxyConfigurationSettings();
    Mockito.doReturn(controlleSettings)
        .when(configService)
        .getControllerConfigurationSettings(Matchers.anyString());
    Mockito.doReturn(manager)
        .when(besDAO)
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());

    // when
    authenticateTMForController(CTRL_ID, manager.getUserId(), "pass");

    // then
    Mockito.verify(besDAO, Mockito.times(0))
        .getUser(Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class));
    Mockito.verify(besDAO, Mockito.times(1))
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());
  }
  @SuppressWarnings("unchecked")
  @Test
  public void testAuthenticateTMForInstance_SSO() throws Throwable {
    // given
    Map<String, String> settings = getProxySettingsForMode("SAML_SP");
    createServiceInstance(
        ProvisioningStatus.COMPLETED, InstanceParameter.BSS_USER, InstanceParameter.BSS_USER_PWD);
    VOUserDetails manager = createVOUserDetails(10000, "user", "tp123");
    manager.setUserRoles(Collections.singleton(UserRoleType.TECHNOLOGY_MANAGER));
    Mockito.doReturn(manager)
        .when(besDAO)
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());
    Mockito.doReturn(new PasswordAuthentication("nobody", ""))
        .when(configService)
        .getWebServiceAuthentication(Matchers.any(ServiceInstance.class), Matchers.anyMap());
    Mockito.doReturn(settings).when(configService).getAllProxyConfigurationSettings();

    // when
    authenticateTMForInstance(CTRL_ID, "appInstanceId", manager.getUserId(), "pass");

    // then
    Mockito.verify(besDAO, Mockito.times(0))
        .getUser(Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class));
    Mockito.verify(besDAO, Mockito.times(2))
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());
  }
 public VOUserDetails authenticate(Map<String, Object> requestContext) {
   Object user =
       requestContext.get(
           useSSO ? XWSSConstants.USERNAME_PROPERTY : BindingProvider.USERNAME_PROPERTY);
   Object pwd =
       requestContext.get(
           useSSO ? XWSSConstants.PASSWORD_PROPERTY : BindingProvider.PASSWORD_PROPERTY);
   if (user != null) {
     Long userKey = null;
     if (useSSO) {
       VOUserDetails userDetails = byId.get(user);
       if (userDetails != null) {
         userKey = Long.valueOf(userDetails.getKey());
       } else {
         throw new ClientTransportException(new RuntimeException());
       }
     } else {
       userKey = Long.valueOf(user.toString());
     }
     if (passwordsByKey.get(userKey) != null && passwordsByKey.get(userKey).equals(pwd)) {
       return byKey.get(userKey);
     }
   }
   throw new ClientTransportException(new RuntimeException());
 }
 private void addUser(VOUserDetails user, String password) {
   if (user != null) {
     if (user.getKey() != 0 && user.getUserId() != null) {
       byId.put(user.getUserId(), user);
       byKey.put(Long.valueOf(user.getKey()), user);
       passwordsByKey.put(Long.valueOf(user.getKey()), password);
     } else {
       throw new IllegalArgumentException("User must have ID and key!");
     }
   }
 }
  @Test(expected = ConfigurationException.class)
  public void testAuthenticateTMForController_noOrgId() throws Throwable {

    // given
    Map<String, String> controllerSettings = new HashMap<>();
    VOUserDetails manager = createVOUserDetails(10000, "user", "tp123");
    Mockito.doReturn(controllerSettings)
        .when(configService)
        .getControllerConfigurationSettings(Matchers.anyString());

    // when
    authenticateTMForController(CTRL_ID, manager.getUserId(), "pass");
  }
  @Ignore
  // TODO test in besDAO
  @Test(expected = ConfigurationException.class)
  public void testAuthenticateTMForInstance_SSO_withoutConfiguredPassword() throws Throwable {

    proxyConfigSettings.put(PlatformConfigurationKey.BSS_AUTH_MODE.name(), "SAML_SP");
    VOUserDetails supplier = createVOUserDetails(10000, "supplier", "tp123");
    controllerConfigSettings.put(ControllerConfigurationKey.BSS_USER_PWD.name(), null);
    // do not add instance specific TP credentials
    createServiceInstance(ProvisioningStatus.COMPLETED, InstanceParameter.PUBLIC_IP);

    authenticateTMForInstance(CTRL_ID, "appInstanceId", supplier.getUserId(), "secret");
    UserBase userBase = new UserBase();
    userBase.addUser(supplier, "secret");
    identityService = userBase.mockIdentityService();
  }
  @Test(expected = AuthenticationException.class)
  public void testAuthenticateTMForInstance_wrongOrg() throws Throwable {
    // given
    createServiceInstance(ProvisioningStatus.COMPLETED, InstanceParameter.PUBLIC_IP);
    VOUserDetails org = createVOUserDetails(10000, "supplier", "tp123");
    VOUserDetails wrongOrg = createVOUserDetails(20001, "user", "customer");
    Mockito.doReturn(org)
        .doReturn(wrongOrg)
        .when(besDAO)
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());

    // when
    authenticateTMForInstance(
        CTRL_ID, "appInstanceId", new PasswordAuthentication(wrongOrg.getUserId(), "secret"));
  }
  @SuppressWarnings("unchecked")
  @Test(expected = AuthenticationException.class)
  public void testAuthenticateTMForInstance_wrongRole() throws Throwable {
    // given
    createServiceInstance(ProvisioningStatus.COMPLETED, InstanceParameter.PUBLIC_IP);
    VOUserDetails user = createVOUserDetails(10000, "supplier", "tp123");
    user.addUserRole(UserRoleType.MARKETPLACE_OWNER);
    Mockito.doReturn(user)
        .when(besDAO)
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());
    Mockito.doReturn(new PasswordAuthentication("nobody", ""))
        .when(configService)
        .getWebServiceAuthentication(Matchers.any(ServiceInstance.class), Matchers.anyMap());

    // when
    authenticateTMForInstance(
        CTRL_ID, "appInstanceId", new PasswordAuthentication("supplier", "secret"));
  }
  @Test
  public void testAuthenticateAdministrator_Params() throws Throwable {
    // given
    VOUserDetails admin = createVOUserDetails(1000, "admin", "app");
    admin.setUserRoles(Collections.singleton(UserRoleType.ORGANIZATION_ADMIN));
    Mockito.doReturn(new VOUserDetails())
        .when(authService)
        .authenticateUser(
            Matchers.any(ServiceInstance.class),
            Matchers.anyString(),
            Matchers.any(PasswordAuthentication.class),
            Matchers.any(UserRoleType.class));

    // when
    authService.authenticateAdministrator(defaultAuth);

    // then
    Mockito.verify(authService)
        .authenticateUser(null, null, defaultAuth, UserRoleType.ORGANIZATION_ADMIN);
  }
  @SuppressWarnings("unchecked")
  @Test(expected = APPlatformException.class)
  public void testAuthenticateTMForInstance_OperationNotPermitted() throws Throwable {
    // given
    createServiceInstance(ProvisioningStatus.COMPLETED, InstanceParameter.PUBLIC_IP);
    VOUserDetails currentUserDetails =
        createVOUserDetails(1000, defaultAuth.getUserName(), "orgid");
    Mockito.doReturn(currentUserDetails)
        .when(besDAO)
        .getUserDetails(
            Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class), Matchers.anyString());
    Mockito.doReturn(new PasswordAuthentication(currentUserDetails.getUserId(), "pass"))
        .when(configService)
        .getWebServiceAuthentication(Matchers.any(ServiceInstance.class), Matchers.anyMap());
    Mockito.doThrow(new APPlatformException("any"))
        .when(besDAO)
        .getUser(Matchers.any(ServiceInstance.class), Matchers.any(VOUser.class));

    // when
    authenticateTMForInstance(CTRL_ID, "appInstanceId", defaultAuth);
  }
  @Before
  public void setup() throws Exception {
    filter = new AuthorizationFilter();
    filter.authService = mock(APPAuthenticationServiceBean.class);

    VOUserDetails user = new VOUserDetails();
    user.setLocale("de");
    doReturn(user)
        .when(filter.authService)
        .authenticateAdministrator(any(PasswordAuthentication.class));

    chain = mock(FilterChain.class);
    config = mock(FilterConfig.class);
    req = mock(HttpServletRequest.class);
    resp = mock(HttpServletResponse.class);
    session = mock(HttpSession.class);

    when(req.getSession()).thenReturn(session);
    when(req.getLocale()).thenReturn(new Locale("en"));
    when(req.getServletPath()).thenReturn("/xxx");
    when(config.getInitParameter(any(String.class))).thenReturn("css");
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
      response.getWriter().print(HttpServletResponse.SC_UNAUTHORIZED);
      return;
    }

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    HttpSession session = httpRequest.getSession();

    if (!httpRequest.getServletPath().matches(excludeUrlPattern)) {
      String requireTMforOrg = null;
      String controllerId = null;

      String path = httpRequest.getServletPath();
      if (path != null && path.startsWith("/controller/")) {
        controllerId = httpRequest.getParameter(SessionConstants.SESSION_CTRL_ID);
        if (controllerId == null || controllerId.trim().isEmpty()) {
          controllerId = (String) session.getAttribute(SessionConstants.SESSION_CTRL_ID);
        }
        HashMap<String, String> organizations = configService.getControllerOrganizations();
        if (!organizations.containsKey(controllerId) || organizations.get(controllerId) == null) {
          httpResponse.setStatus(404);
          return;
        }
        requireTMforOrg = organizations.get(controllerId);
      }

      Object loggedInUserId = session.getAttribute(SessionConstants.SESSION_USER_ID);
      if (loggedInUserId != null) {
        if (requireTMforOrg != null) {
          Object loggedInUserOrgId = session.getAttribute(SessionConstants.SESSION_USER_ORG_ID);
          Object loggedInUserRoles = session.getAttribute(SessionConstants.SESSION_USER_ROLES);
          if (!requireTMforOrg.equals(loggedInUserOrgId)
              || loggedInUserRoles == null
              || !(loggedInUserRoles instanceof Set)
              || !((Set<?>) loggedInUserRoles).contains(UserRoleType.TECHNOLOGY_MANAGER)) {

            send401(httpRequest, httpResponse, session, true);
            return;
          }
        } else {
          if (!Boolean.parseBoolean(
              "" + session.getAttribute(SessionConstants.SESSION_USER_IS_ADMIN))) {
            send401(httpRequest, httpResponse, session, false);
            return;
          }
        }

        // logged in with valid org and role => continue normally
        session.setAttribute(SessionConstants.SESSION_CTRL_ID, controllerId);
        chain.doFilter(httpRequest, response);
        return;
      }

      // Check HTTP Basic authentication
      String authHeader = httpRequest.getHeader("Authorization");
      if (authHeader != null) {
        StringTokenizer st = new StringTokenizer(authHeader);
        if (st.hasMoreTokens()) {
          String basic = st.nextToken();

          // only handle HTTP Basic authentication
          if (basic.equalsIgnoreCase("basic")) {
            String credentials = st.nextToken();
            String userPass = new String(Base64.decodeBase64(credentials));

            // The decoded string is in the form "userID:password".
            int p = userPass.indexOf(":");
            if (p != -1) {
              String userName = userPass.substring(0, p);
              String password = userPass.substring(p + 1);
              PasswordAuthentication auth = new PasswordAuthentication(userName, password);

              try {

                // Check authority
                VOUserDetails voUser = null;
                if (requireTMforOrg != null) {
                  voUser = authService.getAuthenticatedTMForController(controllerId, auth);
                  session.removeAttribute(SessionConstants.SESSION_USER_IS_ADMIN);
                  session.setAttribute(SessionConstants.SESSION_CTRL_ID, controllerId);
                  session.setAttribute("loggedInUserOrgId", voUser.getOrganizationId());
                  session.setAttribute("loggedInUserRoles", voUser.getUserRoles());
                } else {
                  voUser = authService.authenticateAdministrator(auth);
                  session.setAttribute(SessionConstants.SESSION_USER_IS_ADMIN, "true");
                  session.setAttribute("loggedInUserOrgId", voUser.getOrganizationId());
                  session.setAttribute("loggedInUserRoles", voUser.getUserRoles());
                }
                session.setAttribute(SessionConstants.SESSION_USER_LOCALE, voUser.getLocale());

                // Valid => store data in session
                session.setAttribute(SessionConstants.SESSION_USER_ID, userName);
                session.setAttribute(SessionConstants.SESSION_USER_PASSWORD, password);

                // And continue
                chain.doFilter(httpRequest, response);
                return;

              } catch (Exception e) {
                if (null != logger) {
                  logger.error("doFilter: " + e.getMessage());
                }
              }
            }
          }
        }
      }
      send401(httpRequest, httpResponse, session, requireTMforOrg != null);
    } else {
      chain.doFilter(request, response);
    }
  }