protected String getAttribute(
      IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
    String name = mapperModel.getConfig().get(ATTRIBUTE_NAME);
    if (name != null && name.trim().equals("")) name = null;
    String friendly = mapperModel.getConfig().get(ATTRIBUTE_FRIENDLY_NAME);
    if (friendly != null && friendly.trim().equals("")) friendly = null;
    AssertionType assertion =
        (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION);
    for (AttributeStatementType statement : assertion.getAttributeStatements()) {
      for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
        AttributeType attr = choice.getAttribute();
        if (name != null && !name.equals(attr.getName())) continue;
        if (friendly != null && !friendly.equals(attr.getFriendlyName())) continue;

        List<Object> attributeValue = attr.getAttributeValue();
        if (attributeValue == null || attributeValue.isEmpty()) return null;
        return attributeValue.get(0).toString();
      }
    }
    return null;
  }
  @Test
  public void testAttributes() throws Exception {
    // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse
    // so we can look
    // at the assertions sent.  This is because Picketlink, AFAICT, does not give you any way to get
    // access to
    // the assertion.

    {
      SamlSPFacade.samlResponse = null;
      driver.navigate().to("http://*****:*****@redhat.com");
            email = true;
          } else if (attr.getName().equals("phone")) {
            Assert.assertEquals(
                JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
            Assert.assertEquals(attr.getAttributeValue().get(0), "617");
            phone = true;
          } else if (attr.getName().equals("Role")) {
            if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
            if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
          }
        }
      }

      Assert.assertTrue(email);
      Assert.assertTrue(phone);
      Assert.assertTrue(userRole);
      Assert.assertTrue(managerRole);
    }

    keycloakRule.update(
        new KeycloakRule.KeycloakSetup() {
          @Override
          public void config(
              RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
            ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
            for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
              if (mapper.getName().equals("role-list")) {
                app.removeProtocolMapper(mapper);
                mapper.setId(null);
                mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
                mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
                app.addProtocolMapper(mapper);
              }
            }
            app.addProtocolMapper(
                HardcodedAttributeMapper.create(
                    "hardcoded-attribute",
                    "hardcoded-attribute",
                    "Basic",
                    null,
                    "hard",
                    false,
                    null));
            app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
            app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
            app.addProtocolMapper(
                RoleNameMapper.create(
                    "renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
          }
        },
        "demo");

    System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");

    {
      SamlSPFacade.samlResponse = null;
      driver.navigate().to("http://localhost:8081/employee/");
      System.out.println(driver.getCurrentUrl());
      Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
      Assert.assertNotNull(SamlSPFacade.samlResponse);
      SAML2Response saml2Response = new SAML2Response();
      byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
      ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
      Assert.assertTrue(rt.getAssertions().size() == 1);
      AssertionType assertion = rt.getAssertions().get(0).getAssertion();

      // test attributes and roles

      boolean userRole = false;
      boolean managerRole = false;
      boolean single = false;
      boolean hardcodedRole = false;
      boolean hardcodedAttribute = false;
      boolean peeOn = false;
      for (AttributeStatementType statement : assertion.getAttributeStatements()) {
        for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
          AttributeType attr = choice.getAttribute();
          if (attr.getName().equals("memberOf")) {
            if (single) Assert.fail("too many role attributes");
            single = true;
            for (Object value : attr.getAttributeValue()) {
              if (value.equals("el-jefe")) managerRole = true;
              if (value.equals("user")) userRole = true;
              if (value.equals("hardcoded-role")) hardcodedRole = true;
              if (value.equals("pee-on")) peeOn = true;
            }
          } else if (attr.getName().equals("hardcoded-attribute")) {
            hardcodedAttribute = true;
            Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
          }
        }
      }

      Assert.assertTrue(single);
      Assert.assertTrue(hardcodedAttribute);
      Assert.assertTrue(hardcodedRole);
      Assert.assertTrue(peeOn);
      Assert.assertTrue(userRole);
      Assert.assertTrue(managerRole);
    }
  }
  protected AuthOutcome handleLoginResponse(
      ResponseType responseType, OnSessionCreated onCreateSession) {

    AssertionType assertion = null;
    try {
      assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey());
      if (AssertionUtil.hasExpired(assertion)) {
        return initiateLogin();
      }
    } catch (Exception e) {
      log.error("Error extracting SAML assertion: " + e.getMessage());
      challenge =
          new AuthChallenge() {
            @Override
            public boolean challenge(HttpFacade exchange) {
              SamlAuthenticationError error =
                  new SamlAuthenticationError(SamlAuthenticationError.Reason.EXTRACTION_FAILURE);
              exchange.getRequest().setError(error);
              exchange.getResponse().sendError(403);
              return true;
            }

            @Override
            public int getResponseCode() {
              return 403;
            }
          };
    }

    SubjectType subject = assertion.getSubject();
    SubjectType.STSubType subType = subject.getSubType();
    NameIDType subjectNameID = (NameIDType) subType.getBaseID();
    String principalName = subjectNameID.getValue();

    final Set<String> roles = new HashSet<>();
    MultivaluedHashMap<String, String> attributes = new MultivaluedHashMap<>();
    MultivaluedHashMap<String, String> friendlyAttributes = new MultivaluedHashMap<>();

    Set<StatementAbstractType> statements = assertion.getStatements();
    for (StatementAbstractType statement : statements) {
      if (statement instanceof AttributeStatementType) {
        AttributeStatementType attributeStatement = (AttributeStatementType) statement;
        List<AttributeStatementType.ASTChoiceType> attList = attributeStatement.getAttributes();
        for (AttributeStatementType.ASTChoiceType obj : attList) {
          AttributeType attr = obj.getAttribute();
          if (isRole(attr)) {
            List<Object> attributeValues = attr.getAttributeValue();
            if (attributeValues != null) {
              for (Object attrValue : attributeValues) {
                String role = getAttributeValue(attrValue);
                log.debugv("Add role: {0}", role);
                roles.add(role);
              }
            }
          } else {
            List<Object> attributeValues = attr.getAttributeValue();
            if (attributeValues != null) {
              for (Object attrValue : attributeValues) {
                String value = getAttributeValue(attrValue);
                if (attr.getName() != null) {
                  attributes.add(attr.getName(), value);
                }
                if (attr.getFriendlyName() != null) {
                  friendlyAttributes.add(attr.getFriendlyName(), value);
                }
              }
            }
          }
        }
      }
    }
    if (deployment.getPrincipalNamePolicy() == SamlDeployment.PrincipalNamePolicy.FROM_ATTRIBUTE) {
      if (deployment.getPrincipalAttributeName() != null) {
        String attribute = attributes.getFirst(deployment.getPrincipalAttributeName());
        if (attribute != null) principalName = attribute;
        else {
          attribute = friendlyAttributes.getFirst(deployment.getPrincipalAttributeName());
          if (attribute != null) principalName = attribute;
        }
      }
    }

    AuthnStatementType authn = null;
    for (Object statement : assertion.getStatements()) {
      if (statement instanceof AuthnStatementType) {
        authn = (AuthnStatementType) statement;
        break;
      }
    }

    URI nameFormat = subjectNameID.getFormat();
    String nameFormatString =
        nameFormat == null
            ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get()
            : nameFormat.toString();
    final SamlPrincipal principal =
        new SamlPrincipal(
            assertion,
            principalName,
            principalName,
            nameFormatString,
            attributes,
            friendlyAttributes);
    String index = authn == null ? null : authn.getSessionIndex();
    final String sessionIndex = index;
    SamlSession account = new SamlSession(principal, roles, sessionIndex);
    sessionStore.saveAccount(account);
    onCreateSession.onSessionCreated(account);

    // redirect to original request, it will be restored
    String redirectUri = sessionStore.getRedirectUri();
    if (redirectUri != null) {
      facade.getResponse().setHeader("Location", redirectUri);
      facade.getResponse().setStatus(302);
      facade.getResponse().end();
    } else {
      log.debug("IDP initiated invocation");
    }
    log.debug("AUTHENTICATED authn");

    return AuthOutcome.AUTHENTICATED;
  }