text:
package org.keycloak.testsuite.account;

import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.authentication.authenticators.browser.WebAuthnAuthenticatorFactory;
import org.keycloak.authentication.authenticators.browser.WebAuthnPasswordlessAuthenticatorFactory;
import org.keycloak.authentication.requiredactions.WebAuthnPasswordlessRegisterFactory;
import org.keycloak.authentication.requiredactions.WebAuthnRegisterFactory;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.Profile;
import org.keycloak.common.enums.AccountRestApiVersion;
import org.keycloak.common.util.ObjectUtil;
import org.keycloak.credential.CredentialTypeMetadata;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.models.credential.PasswordCredentialModel;
import org.keycloak.models.credential.WebAuthnCredentialModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.representations.account.ClientRepresentation;
import org.keycloak.representations.account.ConsentRepresentation;
import org.keycloak.representations.account.ConsentScopeRepresentation;
import org.keycloak.representations.account.SessionRepresentation;
import org.keycloak.representations.account.UserRepresentation;
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.ClientScopeRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.ErrorRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.account.AccountCredentialResource;
import org.keycloak.services.util.ResolveRelative;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.TokenUtil;
import org.keycloak.testsuite.util.UserBuilder;

import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

/**
 * @author Stian Thorgersen
 */
@AuthServerContainerExclude(AuthServer.REMOTE)
@EnableFeature(value = Profile.Feature.WEB_AUTHN, skipRestart = true, onlyForProduct = true)
public class AccountRestServiceTest extends AbstractRestServiceTest {

    @Test
    public void testGetProfile() throws IOException {

        UserRepresentation user = SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
        assertEquals("Tom", user.getFirstName());
        assertEquals("Brady", user.getLastName());
        assertEquals("test-user@localhost", user.getEmail());
        assertFalse(user.isEmailVerified());
        assertTrue(user.getAttributes().isEmpty());
    }

    @Test
    public void testUpdateSingleField() throws IOException {
        UserRepresentation user = SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
        String originalUsername = user.getUsername();
        String originalFirstName = user.getFirstName();
        String originalLastName = user.getLastName();
        String originalEmail = user.getEmail();
        Map<String, List<String>> originalAttributes = new HashMap<>(user.getAttributes());

        try {
            RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();

            realmRep.setRegistrationEmailAsUsername(false);
            adminClient.realm("test").update(realmRep);

            user.setFirstName(null);
            user.setLastName("Bob");
            user.setEmail(null);
            user.getAttributes().clear();

            user = updateAndGet(user);

            assertEquals(user.getLastName(), "Bob");
            assertNull(user.getFirstName());
            assertNull(user.getEmail());

        } finally {
            RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
            realmRep.setEditUsernameAllowed(true);
            adminClient.realm("test").update(realmRep);

            user.setUsername(originalUsername);
            user.setFirstName(originalFirstName);
            user.setLastName(originalLastName);
            user.setEmail(originalEmail);
            user.setAttributes(originalAttributes);
            SimpleHttp.Response response = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
            System.out.println(response.asString());
            assertEquals(204, response.getStatus());
        }

    }

    @Test
    public void testUpdateProfile() throws IOException {
        UserRepresentation user = SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
        String originalUsername = user.getUsername();
        String originalFirstName = user.getFirstName();
        String originalLastName = user.getLastName();
        String originalEmail = user.getEmail();
        Map<String, List<String>> originalAttributes = new HashMap<>(user.getAttributes());

        try {
            RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();

            realmRep.setRegistrationEmailAsUsername(false);
            adminClient.realm("test").update(realmRep);

            user.setFirstName("Homer");
            user.setLastName("Simpsons");
            user.getAttributes().put("attr1", Collections.singletonList("val1"));
            user.getAttributes().put("attr2", Collections.singletonList("val2"));

            user = updateAndGet(user);

            assertEquals("Homer", user.getFirstName());
            assertEquals("Simpsons", user.getLastName());
            assertEquals(2, user.getAttributes().size());
            assertEquals(1, user.getAttributes().get("attr1").size());
            assertEquals("val1", user.getAttributes().get("attr1").get(0));
            assertEquals(1, user.getAttributes().get("attr2").size());
            assertEquals("val2", user.getAttributes().get("attr2").get(0));

            // Update attributes
            user.getAttributes().remove("attr1");
            user.getAttributes().get("attr2").add("val3");

            user = updateAndGet(user);

            assertEquals(1, user.getAttributes().size());
            assertEquals(2, user.getAttributes().get("attr2").size());
            assertThat(user.getAttributes().get("attr2"), containsInAnyOrder("val2", "val3"));

            // Update email
            user.setEmail("bobby@localhost");
            user = updateAndGet(user);
            assertEquals("bobby@localhost", user.getEmail());

            user.setEmail("john-doh@localhost");
            updateError(user, 409, Messages.EMAIL_EXISTS);

            user.setEmail("test-user@localhost");
            user = updateAndGet(user);
            assertEquals("test-user@localhost", user.getEmail());

            user.setUsername("john-doh@localhost");
            updateError(user, 409, Messages.USERNAME_EXISTS);

            user.setUsername("test-user@localhost");
            user = updateAndGet(user);
            assertEquals("test-user@localhost", user.getUsername());

            realmRep.setRegistrationEmailAsUsername(true);
            adminClient.realm("test").update(realmRep);

            user.setUsername("updatedUsername");
            user = updateAndGet(user);
            assertEquals("test-user@localhost", user.getUsername());

            realmRep.setRegistrationEmailAsUsername(false);
            adminClient.realm("test").update(realmRep);

            user.setUsername("updatedUsername");
            user = updateAndGet(user);
            assertEquals("updatedusername", user.getUsername());

            realmRep.setEditUsernameAllowed(false);
            realmRep.setRegistrationEmailAsUsername(false);
            adminClient.realm("test").update(realmRep);

            user.setUsername("updatedUsername2");
            updateError(user, 400, Messages.READ_ONLY_USERNAME);
        } finally {
            RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
            realmRep.setEditUsernameAllowed(true);
            adminClient.realm("test").update(realmRep);

            user.setUsername(originalUsername);
            user.setFirstName(originalFirstName);
            user.setLastName(originalLastName);
            user.setEmail(originalEmail);
            user.setAttributes(originalAttributes);
            SimpleHttp.Response response = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
            System.out.println(response.asString());
            assertEquals(204, response.getStatus());
        }

    }

    @Test
    public void testUpdateProfileCannotChangeThroughAttributes() throws IOException {
        UserRepresentation user = SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
        String originalUsername = user.getUsername();
        Map<String, List<String>> originalAttributes = new HashMap<>(user.getAttributes());

        try {
            user.getAttributes().put("username", Collections.singletonList("Username"));
            user.getAttributes().put("attr2", Collections.singletonList("val2"));

            user = updateAndGet(user);

            assertEquals(user.getUsername(), originalUsername);
        } finally {
            RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
            realmRep.setEditUsernameAllowed(true);
            adminClient.realm("test").update(realmRep);

            user.setUsername(originalUsername);
            user.setAttributes(originalAttributes);
            SimpleHttp.Response response = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
            System.out.println(response.asString());
            assertEquals(204, response.getStatus());
        }
    }

    // KEYCLOAK-7572
    @Test
    public void testUpdateProfileWithRegistrationEmailAsUsername() throws IOException {
        RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
        realmRep.setRegistrationEmailAsUsername(true);
        adminClient.realm("test").update(realmRep);

        UserRepresentation user = SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
        String originalFirstname = user.getFirstName();

        try {
            user.setFirstName("Homer1");

            user = updateAndGet(user);

            assertEquals("Homer1", user.getFirstName());
        } finally {
            user.setFirstName(originalFirstname);
            int status = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asStatus();
            assertEquals(204, status);
        }
    }

    private UserRepresentation updateAndGet(UserRepresentation user) throws IOException {
        int status = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asStatus();
        assertEquals(204, status);
        return SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
    }

    private void updateError(UserRepresentation user, int expectedStatus, String expectedMessage) throws IOException {
        SimpleHttp.Response response = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
        assertEquals(expectedStatus, response.getStatus());
        assertEquals(expectedMessage, response.asJson(ErrorRepresentation.class).getErrorMessage());
    }

    @Test
    public void testProfilePermissions() throws IOException {
        TokenUtil noaccessToken = new TokenUtil("no-account-access", "password");
        TokenUtil viewToken = new TokenUtil("view-account-access", "password");

        // Read with no access
        assertEquals(403, SimpleHttp.doGet(getAccountUrl(null), httpClient).header("Accept", "application/json").auth(noaccessToken.getToken()).asStatus());

        // Update with no access
        assertEquals(403, SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(noaccessToken.getToken()).json(new UserRepresentation()).asStatus());

        // Update with read only
        assertEquals(403, SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(viewToken.getToken()).json(new UserRepresentation()).asStatus());
    }

    @Test
    public void testUpdateProfilePermissions() throws IOException {
        TokenUtil noaccessToken = new TokenUtil("no-account-access", "password");
        int status = SimpleHttp.doGet(getAccountUrl(null), httpClient).header("Accept", "application/json").auth(noaccessToken.getToken()).asStatus();
        assertEquals(403, status);

        TokenUtil viewToken = new TokenUtil("view-account-access", "password");
        status = SimpleHttp.doGet(getAccountUrl(null), httpClient).header("Accept", "application/json").auth(viewToken.getToken()).asStatus();
        assertEquals(200, status);
    }

    @Test
    public void testCredentialsGet() throws IOException {
        configureBrowserFlowWithWebAuthnAuthenticator("browser-webauthn");

        // Register requiredActions for WebAuthn and WebAuthn Passwordless
        RequiredActionProviderSimpleRepresentation requiredAction = new RequiredActionProviderSimpleRepresentation();
        requiredAction.setId("12345");
        requiredAction.setName(WebAuthnRegisterFactory.PROVIDER_ID);
        requiredAction.setProviderId(WebAuthnRegisterFactory.PROVIDER_ID);
        testRealm().flows().registerRequiredAction(requiredAction);

        requiredAction = new RequiredActionProviderSimpleRepresentation();
        requiredAction.setId("6789");
        requiredAction.setName(WebAuthnPasswordlessRegisterFactory.PROVIDER_ID);
        requiredAction.setProviderId(WebAuthnPasswordlessRegisterFactory.PROVIDER_ID);
        testRealm().flows().registerRequiredAction(requiredAction);

        List<AccountCredentialResource.CredentialContainer> credentials = getCredentials();

        Assert.assertEquals(4, credentials.size());

        AccountCredentialResource.CredentialContainer password = credentials.get(0);
        assertCredentialContainerExpected(password, PasswordCredentialModel.TYPE, CredentialTypeMetadata.Category.BASIC_AUTHENTICATION.toString(),
                "password-display-name", "password-help-text", "kcAuthenticatorPasswordClass",
                null, UserModel.RequiredAction.UPDATE_PASSWORD.toString(), false, 1);

        CredentialRepresentation password1 = password.getUserCredentials().get(0);
        assertNull(password1.getSecretData());
        Assert.assertNotNull(password1.getCredentialData());

        AccountCredentialResource.CredentialContainer otp = credentials.get(1);
        assertCredentialContainerExpected(otp, OTPCredentialModel.TYPE, CredentialTypeMetadata.Category.TWO_FACTOR.toString(),
                "otp-display-name", "otp-help-text", "kcAuthenticatorOTPClass",
                UserModel.RequiredAction.CONFIGURE_TOTP.toString(), null, true, 0);

        // WebAuthn credentials will be returned, but createAction will be still null because requiredAction "webauthn register" not yet registered
        AccountCredentialResource.CredentialContainer webauthn = credentials.get(2);
        assertCredentialContainerExpected(webauthn, WebAuthnCredentialModel.TYPE_TWOFACTOR, CredentialTypeMetadata.Category.TWO_FACTOR.toString(),
                "webauthn-display-name", "webauthn-help-text", "kcAuthenticatorWebAuthnClass",
                WebAuthnRegisterFactory.PROVIDER_ID, null, true, 0);

        AccountCredentialResource.CredentialContainer webauthnPasswordless = credentials.get(3);
        assertCredentialContainerExpected(webauthnPasswordless, WebAuthnCredentialModel.TYPE_PASSWORDLESS, CredentialTypeMetadata.Category.PASSWORDLESS.toString(),
                "webauthn-passwordless-display-name", "webauthn-passwordless-help-text", "kcAuthenticatorWebAuthnPasswordlessClass",
                WebAuthnPasswordlessRegisterFactory.PROVIDER_ID, null, true, 0);

        // disable WebAuthn passwordless required action. User doesn't have WebAuthnPasswordless credential, so WebAuthnPasswordless credentialType won't be returned
        setRequiredActionEnabledStatus(WebAuthnPasswordlessRegisterFactory.PROVIDER_ID, false);

        credentials = getCredentials();
        assertExpectedCredentialTypes(credentials, PasswordCredentialModel.TYPE, OTPCredentialModel.TYPE, WebAuthnCredentialModel.TYPE_TWOFACTOR);

        // Test that WebAuthn won't be returned when removed from the authentication flow
        removeWebAuthnFlow("browser-webauthn");

        credentials = getCredentials();

        assertExpectedCredentialTypes(credentials, PasswordCredentialModel.TYPE, OTPCredentialModel.TYPE);

        // Test password-only
        credentials = SimpleHttp.doGet(getAccountUrl("credentials?" + AccountCredentialResource.TYPE + "=password"), httpClient)
                .auth(tokenUtil.getToken()).asJson(new TypeReference<List<AccountCredentialResource.CredentialContainer>>() {});
        Assert.assertEquals(1, credentials.size());
        password = credentials.get(0);
        Assert.assertEquals(PasswordCredentialModel.TYPE, password.getType());
        Assert.assertEquals(1, password.getUserCredentials().size());

        // Test password-only and user-credentials
        credentials = SimpleHttp.doGet(getAccountUrl("credentials?" + AccountCredentialResource.TYPE + "=password&" +
                AccountCredentialResource.USER_CREDENTIALS + "=false"), httpClient)
                .auth(tokenUtil.getToken()).asJson(new TypeReference<List<AccountCredentialResource.CredentialContainer>>() {});
        Assert.assertEquals(1, credentials.size());
        password = credentials.get(0);
        Assert.assertEquals(PasswordCredentialModel.TYPE, password.getType());
        assertNull(password.getUserCredentials());
    }

    @Test
    public void testCRUDCredentialOfDifferentUser() throws IOException {
        // Get credential ID of the OTP credential of the different user thant currently logged user
        UserResource user = ApiUtil.findUserByUsernameId(testRealm(), "user-with-one-configured-otp");
        CredentialRepresentation otpCredential = user.credentials().stream()
                .filter(credentialRep -> OTPCredentialModel.TYPE.equals(credentialRep.getType()))
                .findFirst()
                .get();

        // Test that current user can't update the credential, which belongs to the different user
        SimpleHttp.Response response = SimpleHttp
                .doPut(getAccountUrl("credentials/" + otpCredential.getId() + "/label"), httpClient)
                .auth(tokenUtil.getToken())
                .json("new-label")
                .asResponse();
        assertEquals(404, response.getStatus());

        // Test that current user can't delete the credential, which belongs to the different user
        response = SimpleHttp
                .doDelete(getAccountUrl("credentials/" + otpCredential.getId()), httpClient)
                .acceptJson()
                .auth(tokenUtil.getToken())
                .asResponse();
        assertEquals(404, response.getStatus());

        // Assert credential was not updated or removed
        CredentialRepresentation otpCredentialLoaded = user.credentials().stream()
                .filter(credentialRep -> OTPCredentialModel.TYPE.equals(credentialRep.getType()))
                .findFirst()
                .get();
        Assert.assertTrue(ObjectUtil.isEqualOrBothNull(otpCredential.getUserLabel(), otpCredentialLoaded.getUserLabel()));
    }

    // Send REST request to get all credential containers and credentials of current user
    private List<AccountCredentialResource.CredentialContainer> getCredentials() throws IOException {
        return SimpleHttp.doGet(getAccountUrl("credentials"), httpClient)
                .auth(tokenUtil.getToken()).asJson(new TypeReference<List<AccountCredentialResource.CredentialContainer>>() {});
    }

    @Test
    public void testCredentialsGetDisabledOtp() throws IOException {
        // Disable OTP in all built-in flows

        // Disable parent subflow - that should treat OTP execution as disabled too
        AuthenticationExecutionModel.Requirement currentBrowserReq = setExecutionRequirement(DefaultAuthenticationFlows.BROWSER_FLOW,
                "Browser - Conditional OTP", AuthenticationExecutionModel.Requirement.DISABLED);

        // Disable OTP directly in first-broker-login and direct-grant
        AuthenticationExecutionModel.Requirement currentFBLReq = setExecutionRequirement(DefaultAuthenticationFlows.FIRST_BROKER_LOGIN_FLOW,
                "OTP Form", AuthenticationExecutionModel.Requirement.DISABLED);
        AuthenticationExecutionModel.Requirement currentDirectGrantReq = setExecutionRequirement(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW,
                "Direct Grant - Conditional OTP", AuthenticationExecutionModel.Requirement.DISABLED);
        try {
            // Test that OTP credential is not included. Only password
            List<AccountCredentialResource.CredentialContainer> credentials = getCredentials();

            Assert.assertEquals(1, credentials.size());
            Assert.assertEquals(PasswordCredentialModel.TYPE, credentials.get(0).getType());

            // Enable browser subflow. OTP should be available then
            setExecutionRequirement(DefaultAuthenticationFlows.BROWSER_FLOW,
                    "Browser - Conditional OTP", currentBrowserReq);
            credentials = getCredentials();
            Assert.assertEquals(2, credentials.size());
            Assert.assertEquals(OTPCredentialModel.TYPE, credentials.get(1).getType());

            // Disable browser subflow and enable FirstBrokerLogin. OTP should be available then
            setExecutionRequirement(DefaultAuthenticationFlows.BROWSER_FLOW,
                    "Browser - Conditional OTP", AuthenticationExecutionModel.Requirement.DISABLED);
            setExecutionRequirement(DefaultAuthenticationFlows.FIRST_BROKER_LOGIN_FLOW,
                    "OTP Form", currentFBLReq);
            credentials = getCredentials();
            Assert.assertEquals(2, credentials.size());
            Assert.assertEquals(OTPCredentialModel.TYPE, credentials.get(1).getType());
        } finally {
            // Revert flows
            setExecutionRequirement(DefaultAuthenticationFlows.BROWSER_FLOW,
                    "Browser - Conditional OTP", currentBrowserReq);
            setExecutionRequirement(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW,
                    "Direct Grant - Conditional OTP", currentDirectGrantReq);
        }
    }

    @Test
    public void testCredentialsGetWithDisabledOtpRequiredAction() throws IOException {
        // Assert OTP will be returned by default
        List<AccountCredentialResource.CredentialContainer> credentials = getCredentials();
        assertExpectedCredentialTypes(credentials, PasswordCredentialModel.TYPE, OTPCredentialModel.TYPE);

        // Disable OTP required action
        setRequiredActionEnabledStatus(UserModel.RequiredAction.CONFIGURE_TOTP.name(), false);

        // Assert OTP won't be returned
        credentials = getCredentials();
        assertExpectedCredentialTypes(credentials, PasswordCredentialModel.TYPE);

        // Add OTP credential to the user through admin REST API
        UserResource adminUserResource = ApiUtil.findUserByUsernameId(testRealm(), "test-user@localhost");
        org.keycloak.representations.idm.UserRepresentation userRep = UserBuilder.edit(adminUserResource.toRepresentation())
                .totpSecret("abcdefabcdef")
                .build();
        adminUserResource.update(userRep);

        // Assert OTP will be returned without requiredAction
        credentials = getCredentials();
        assertExpectedCredentialTypes(credentials, PasswordCredentialModel.TYPE, OTPCredentialModel.TYPE);
        AccountCredentialResource.CredentialContainer otpCredential = credentials.get(1);
        assertNull(otpCredential.getCreateAction());
        assertNull(otpCredential.getUpdateAction());

        // Revert - re-enable requiredAction and remove OTP credential from the user
        setRequiredActionEnabledStatus(UserModel.RequiredAction.CONFIGURE_TOTP.name(), true);

        String otpCredentialId = adminUserResource.credentials().stream()
                .filter(credential -> OTPCredentialModel.TYPE.equals(credential.getType()))
                .findFirst()
                .get()
                .getId();
        adminUserResource.removeCredential(otpCredentialId);
    }

    private void setRequiredActionEnabledStatus(String requiredActionProviderId, boolean enabled) {
        RequiredActionProviderRepresentation requiredActionRep = testRealm().flows().getRequiredAction(requiredActionProviderId);
        requiredActionRep.setEnabled(enabled);
        testRealm().flows().updateRequiredAction(requiredActionProviderId, requiredActionRep);
    }

    private void assertExpectedCredentialTypes(List<AccountCredentialResource.CredentialContainer> credentialTypes, String... expectedCredentialTypes) {
        Assert.assertEquals(credentialTypes.size(), expectedCredentialTypes.length);
        int i = 0;
        for (AccountCredentialResource.CredentialContainer credential : credentialTypes) {
            Assert.assertEquals(credential.getType(), expectedCredentialTypes[i]);
            i++;
        }
    }

    @Test
    public void testCredentialsForUserWithoutPassword() throws IOException {
        // This is just to call REST to ensure tokenUtil will authenticate user and create the tokens.
        // We won't be able to authenticate later as user won't have password
        List<AccountCredentialResource.CredentialContainer> credentials = getCredentials();

        // Remove password from the user now
        UserResource user = ApiUtil.findUserByUsernameId(testRealm(), "test-user@localhost");
        for (CredentialRepresentation credential : user.credentials()) {
            if (PasswordCredentialModel.TYPE.equals(credential.getType())) {
                user.removeCredential(credential.getId());
            }
        }

        // Get credentials. Ensure user doesn't have password credential and create action is UPDATE_PASSWORD
        credentials = getCredentials();
        AccountCredentialResource.CredentialContainer password = credentials.get(0);
        assertCredentialContainerExpected(password, PasswordCredentialModel.TYPE, CredentialTypeMetadata.Category.BASIC_AUTHENTICATION.toString(),
                "password-display-name", "password-help-text", "kcAuthenticatorPasswordClass",
                UserModel.RequiredAction.UPDATE_PASSWORD.toString(), null, false, 0);

        // Re-add the password to the user
        ApiUtil.resetUserPassword(user, "password", false);

    }

    // Sets new requirement and returns current requirement
    private AuthenticationExecutionModel.Requirement setExecutionRequirement(String flowAlias, String executionDisplayName, AuthenticationExecutionModel.Requirement newRequirement) {
        List<AuthenticationExecutionInfoRepresentation> executionInfos = testRealm().flows().getExecutions(flowAlias);
        for (AuthenticationExecutionInfoRepresentation exInfo : executionInfos) {
            if (executionDisplayName.equals(exInfo.getDisplayName())) {
                AuthenticationExecutionModel.Requirement currentRequirement = AuthenticationExecutionModel.Requirement.valueOf(exInfo.getRequirement());
                exInfo.setRequirement(newRequirement.toString());
                testRealm().flows().updateExecutions(flowAlias, exInfo);
                return currentRequirement;
            }
        }

        throw new IllegalStateException("Not found execution '" + executionDisplayName + "' in flow '" + flowAlias + "'.");
    }

    private void configureBrowserFlowWithWebAuthnAuthenticator(String newFlowAlias) {
        HashMap<String, String> params = new HashMap<>();
        params.put("newName", newFlowAlias);
        Response response = testRealm().flows().copy("browser", params);
        response.close();
        String flowId = AbstractAuthenticationTest.findFlowByAlias(newFlowAlias, testRealm().flows().getFlows()).getId();

        AuthenticationExecutionRepresentation execution = new AuthenticationExecutionRepresentation();
        execution.setParentFlow(flowId);
        execution.setAuthenticator(WebAuthnAuthenticatorFactory.PROVIDER_ID);
        execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString());
        response = testRealm().flows().addExecution(execution);
        response.close();

        execution = new AuthenticationExecutionRepresentation();
        execution.setParentFlow(flowId);
        execution.setAuthenticator( WebAuthnPasswordlessAuthenticatorFactory.PROVIDER_ID);
        execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE.toString());
        response = testRealm().flows().addExecution(execution);
        response.close();
    }

    private void removeWebAuthnFlow(String flowToDeleteAlias) {
        List<AuthenticationFlowRepresentation> flows = testRealm().flows().getFlows();
        AuthenticationFlowRepresentation flowRepresentation = AbstractAuthenticationTest.findFlowByAlias(flowToDeleteAlias, flows);
        testRealm().flows().deleteFlow(flowRepresentation.getId());
    }

    private void assertCredentialContainerExpected(AccountCredentialResource.CredentialContainer credential, String type, String category, String displayName, String helpText, String iconCssClass,
                                                   String createAction, String updateAction, boolean removeable, int userCredentialsCount) {
        Assert.assertEquals(type, credential.getType());
        Assert.assertEquals(category, credential.getCategory());
        Assert.assertEquals(displayName, credential.getDisplayName());
        Assert.assertEquals(helpText, credential.getHelptext());
        Assert.assertEquals(iconCssClass, credential.getIconCssClass());
        Assert.assertEquals(createAction, credential.getCreateAction());
        Assert.assertEquals(updateAction, credential.getUpdateAction());
        Assert.assertEquals(removeable, credential.isRemoveable());
        Assert.assertEquals(userCredentialsCount, credential.getUserCredentials().size());
    }

    public void testDeleteSessions() throws IOException {
        TokenUtil viewToken = new TokenUtil("view-account-access", "password");
        oauth.doLogin("view-account-access", "password");
        List<SessionRepresentation> sessions = SimpleHttp.doGet(getAccountUrl("sessions"), httpClient).auth(viewToken.getToken()).asJson(new TypeReference<List<SessionRepresentation>>() {});
        assertEquals(2, sessions.size());
        int status = SimpleHttp.doDelete(getAccountUrl("sessions?current=false"), httpClient).acceptJson().auth(viewToken.getToken()).asStatus();
        assertEquals(200, status);
        sessions = SimpleHttp.doGet(getAccountUrl("sessions"), httpClient).auth(viewToken.getToken()).asJson(new TypeReference<List<SessionRepresentation>>() {});
        assertEquals(1, sessions.size());
    }

    @Test
    public void listApplications() throws Exception {
        oauth.clientId("in-use-client");
        OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "view-applications-access", "password");
        assertNull(tokenResponse.getErrorDescription());

        TokenUtil token = new TokenUtil("view-applications-access", "password");
        List<ClientRepresentation> applications = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asJson(new TypeReference<List<ClientRepresentation>>() {
                });
        assertFalse(applications.isEmpty());

        Map<String, ClientRepresentation> apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
        Assert.assertThat(apps.keySet(), containsInAnyOrder("in-use-client", "always-display-client"));

        assertClientRep(apps.get("in-use-client"), "In Use Client", null, false, true, false, null, inUseClientAppUri);
        assertClientRep(apps.get("always-display-client"), "Always Display Client", null, false, false, false, null, alwaysDisplayClientAppUri);
    }

    @Test
    public void listApplicationsFiltered() throws Exception {
        oauth.clientId("in-use-client");
        OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "view-applications-access", "password");
        assertNull(tokenResponse.getErrorDescription());

        TokenUtil token = new TokenUtil("view-applications-access", "password");
        List<ClientRepresentation> applications = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .param("name", "In Use")
                .auth(token.getToken())
                .asJson(new TypeReference<List<ClientRepresentation>>() {
                });
        assertFalse(applications.isEmpty());

        Map<String, ClientRepresentation> apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
        Assert.assertThat(apps.keySet(), containsInAnyOrder("in-use-client"));

        assertClientRep(apps.get("in-use-client"), "In Use Client", null, false, true, false, null, inUseClientAppUri);
    }

    @Test
    public void listApplicationsOfflineAccess() throws Exception {
        oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
        oauth.clientId("offline-client");
        OAuthClient.AccessTokenResponse offlineTokenResponse = oauth.doGrantAccessTokenRequest("secret1", "view-applications-access", "password");
        assertNull(offlineTokenResponse.getErrorDescription());

        TokenUtil token = new TokenUtil("view-applications-access", "password");
        List<ClientRepresentation> applications = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asJson(new TypeReference<List<ClientRepresentation>>() {
                });
        assertFalse(applications.isEmpty());

        Map<String, ClientRepresentation> apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
        Assert.assertThat(apps.keySet(), containsInAnyOrder("offline-client", "always-display-client"));

        assertClientRep(apps.get("offline-client"), "Offline Client", null, false, true, true, null, offlineClientAppUri);
    }

    @Test
    public void listApplicationsThirdParty() throws Exception {
        String appId = "third-party";
        TokenUtil token = new TokenUtil("view-applications-access", "password");

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));
        SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);

        List<ClientRepresentation> applications = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asJson(new TypeReference<List<ClientRepresentation>>() {
                });
        assertFalse(applications.isEmpty());

        SimpleHttp
                .doDelete(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();

        Map<String, ClientRepresentation> apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
        Assert.assertThat(apps.keySet(), containsInAnyOrder(appId, "always-display-client"));

        ClientRepresentation app = apps.get(appId);
        assertClientRep(app, null, "A third party application", true, false, false, null, "http://localhost:8180/auth/realms/master/app/auth");
        assertFalse(app.getConsent().getGrantedScopes().isEmpty());
        ConsentScopeRepresentation grantedScope = app.getConsent().getGrantedScopes().get(0);
        assertEquals(clientScopeRepresentation.getId(), grantedScope.getId());
        assertEquals(clientScopeRepresentation.getName(), grantedScope.getName());
    }

    @Test
    public void listApplicationsWithRootUrl() throws Exception {
        oauth.clientId("root-url-client");
        OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("password", "view-applications-access", "password");
        assertNull(tokenResponse.getErrorDescription());

        TokenUtil token = new TokenUtil("view-applications-access", "password");
        List<ClientRepresentation> applications = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asJson(new TypeReference<List<ClientRepresentation>>() {
                });
        assertFalse(applications.isEmpty());

        Map<String, ClientRepresentation> apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
        Assert.assertThat(apps.keySet(), containsInAnyOrder("root-url-client", "always-display-client"));

        assertClientRep(apps.get("root-url-client"), null, null, false, true, false, "http://localhost:8180/foo/bar", "/baz");
    }

    private void assertClientRep(ClientRepresentation clientRep, String name, String description, boolean userConsentRequired, boolean inUse, boolean offlineAccess, String rootUrl, String baseUrl) {
        assertNotNull(clientRep);
        assertEquals(name, clientRep.getClientName());
        assertEquals(description, clientRep.getDescription());
        assertEquals(userConsentRequired, clientRep.isUserConsentRequired());
        assertEquals(inUse, clientRep.isInUse());
        assertEquals(offlineAccess, clientRep.isOfflineAccess());
        assertEquals(rootUrl, clientRep.getRootUrl());
        assertEquals(baseUrl, clientRep.getBaseUrl());
        assertEquals(ResolveRelative.resolveRelativeUri(null, null, rootUrl, baseUrl), clientRep.getEffectiveUrl());
    }

    @Test
    public void listApplicationsWithoutPermission() throws IOException {
        TokenUtil token = new TokenUtil("no-account-access", "password");
        SimpleHttp.Response response = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(403, response.getStatus());
    }

    @Test
    public void getNotExistingApplication() throws IOException {
        TokenUtil token = new TokenUtil("view-applications-access", "password");
        String appId = "not-existing";
        SimpleHttp.Response response = SimpleHttp
                .doGet(getAccountUrl("applications/" + appId), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(404, response.getStatus());
    }

    @Test
    public void createConsentForClient() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation.getCreatedDate() > 0);
        assertTrue(consentRepresentation.getLastUpdatedDate() > 0);
        assertEquals(1, consentRepresentation.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation.getGrantedScopes().get(0).getId());
    }

    @Test
    public void updateConsentForClient() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation.getCreatedDate() > 0);
        assertTrue(consentRepresentation.getLastUpdatedDate() > 0);
        assertEquals(1, consentRepresentation.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation.getGrantedScopes().get(0).getId());

        clientScopeRepresentation = testRealm().clientScopes().findAll().get(1);
        consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation2 = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation2.getCreatedDate() > 0);
        assertEquals(consentRepresentation.getCreatedDate(), consentRepresentation2.getCreatedDate());
        assertTrue(consentRepresentation2.getLastUpdatedDate() > 0);
        assertTrue(consentRepresentation2.getLastUpdatedDate() > consentRepresentation.getLastUpdatedDate());
        assertEquals(1, consentRepresentation2.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation2.getGrantedScopes().get(0).getId());
    }

    @Test
    public void createConsentForNotExistingClient() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "not-existing";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        SimpleHttp.Response response = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asResponse();

        assertEquals(404, response.getStatus());
    }

    @Test
    public void createConsentForClientWithoutPermission() throws IOException {
        TokenUtil token = new TokenUtil("view-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        SimpleHttp.Response response = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asResponse();

        assertEquals(403, response.getStatus());
    }

    @Test
    public void createConsentForClientWithPut() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation = SimpleHttp
                .doPut(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation.getCreatedDate() > 0);
        assertTrue(consentRepresentation.getLastUpdatedDate() > 0);
        assertEquals(1, consentRepresentation.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation.getGrantedScopes().get(0).getId());
    }

    @Test
    public void updateConsentForClientWithPut() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation = SimpleHttp
                .doPut(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation.getCreatedDate() > 0);
        assertTrue(consentRepresentation.getLastUpdatedDate() > 0);
        assertEquals(1, consentRepresentation.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation.getGrantedScopes().get(0).getId());

        clientScopeRepresentation = testRealm().clientScopes().findAll().get(1);
        consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation2 = SimpleHttp
                .doPut(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation2.getCreatedDate() > 0);
        assertEquals(consentRepresentation.getCreatedDate(), consentRepresentation2.getCreatedDate());
        assertTrue(consentRepresentation2.getLastUpdatedDate() > 0);
        assertTrue(consentRepresentation2.getLastUpdatedDate() > consentRepresentation.getLastUpdatedDate());
        assertEquals(1, consentRepresentation2.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation2.getGrantedScopes().get(0).getId());
    }

    @Test
    public void createConsentForNotExistingClientWithPut() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "not-existing";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        SimpleHttp.Response response = SimpleHttp
                .doPut(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asResponse();

        assertEquals(404, response.getStatus());
    }

    @Test
    public void createConsentForClientWithoutPermissionWithPut() throws IOException {
        TokenUtil token = new TokenUtil("view-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        SimpleHttp.Response response = SimpleHttp
                .doPut(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asResponse();

        assertEquals(403, response.getStatus());
    }

    @Test
    public void getConsentForClient() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation1 = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation1.getCreatedDate() > 0);
        assertTrue(consentRepresentation1.getLastUpdatedDate() > 0);
        assertEquals(1, consentRepresentation1.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation1.getGrantedScopes().get(0).getId());

        ConsentRepresentation consentRepresentation2 = SimpleHttp
                .doGet(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertEquals(consentRepresentation1.getLastUpdatedDate(), consentRepresentation2.getLastUpdatedDate());
        assertEquals(consentRepresentation1.getCreatedDate(), consentRepresentation2.getCreatedDate());
        assertEquals(consentRepresentation1.getGrantedScopes().get(0).getId(), consentRepresentation2.getGrantedScopes().get(0).getId());
    }

    @Test
    public void getConsentForNotExistingClient() throws IOException {
        TokenUtil token = new TokenUtil("view-consent-access", "password");
        String appId = "not-existing";
        SimpleHttp.Response response = SimpleHttp
                .doGet(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(404, response.getStatus());
    }

    @Test
    public void getNotExistingConsentForClient() throws IOException {
        TokenUtil token = new TokenUtil("view-consent-access", "password");
        String appId = "security-admin-console";
        SimpleHttp.Response response = SimpleHttp
                .doGet(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(204, response.getStatus());
    }

    @Test
    public void getConsentWithoutPermission() throws IOException {
        TokenUtil token = new TokenUtil("no-account-access", "password");
        String appId = "security-admin-console";
        SimpleHttp.Response response = SimpleHttp
                .doGet(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(403, response.getStatus());
    }

    @Test
    public void deleteConsentForClient() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "security-admin-console";

        ClientScopeRepresentation clientScopeRepresentation = testRealm().clientScopes().findAll().get(0);
        ConsentScopeRepresentation consentScopeRepresentation = new ConsentScopeRepresentation();
        consentScopeRepresentation.setId(clientScopeRepresentation.getId());

        ConsentRepresentation requestedConsent = new ConsentRepresentation();
        requestedConsent.setGrantedScopes(Collections.singletonList(consentScopeRepresentation));

        ConsentRepresentation consentRepresentation = SimpleHttp
                .doPost(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .json(requestedConsent)
                .auth(token.getToken())
                .asJson(ConsentRepresentation.class);
        assertTrue(consentRepresentation.getCreatedDate() > 0);
        assertTrue(consentRepresentation.getLastUpdatedDate() > 0);
        assertEquals(1, consentRepresentation.getGrantedScopes().size());
        assertEquals(consentScopeRepresentation.getId(), consentRepresentation.getGrantedScopes().get(0).getId());

        SimpleHttp.Response response = SimpleHttp
                .doDelete(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(204, response.getStatus());

        response = SimpleHttp
                .doDelete(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(204, response.getStatus());
    }

    @Test
    public void deleteConsentForNotExistingClient() throws IOException {
        TokenUtil token = new TokenUtil("manage-consent-access", "password");
        String appId = "not-existing";
        SimpleHttp.Response response = SimpleHttp
                .doDelete(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(404, response.getStatus());
    }

    @Test
    public void deleteConsentWithoutPermission() throws IOException {
        TokenUtil token = new TokenUtil("view-consent-access", "password");
        String appId = "security-admin-console";
        SimpleHttp.Response response = SimpleHttp
                .doDelete(getAccountUrl("applications/" + appId + "/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(403, response.getStatus());
    }

    //KEYCLOAK-14344
    @Test
    public void revokeOfflineAccess() throws Exception {
        oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
        oauth.clientId("offline-client");
        OAuthClient.AccessTokenResponse offlineTokenResponse = oauth.doGrantAccessTokenRequest("secret1", "view-applications-access", "password");
        assertNull(offlineTokenResponse.getErrorDescription());

        TokenUtil token = new TokenUtil("view-applications-access", "password");

        SimpleHttp.Response response = SimpleHttp
                .doDelete(getAccountUrl("applications/offline-client/consent"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asResponse();
        assertEquals(204, response.getStatus());

        List<ClientRepresentation> applications = SimpleHttp
                .doGet(getAccountUrl("applications"), httpClient)
                .header("Accept", "application/json")
                .auth(token.getToken())
                .asJson(new TypeReference<List<ClientRepresentation>>() {
                });
        assertFalse(applications.isEmpty());

        Map<String, ClientRepresentation> apps = applications.stream().collect(Collectors.toMap(x -> x.getClientId(), x -> x));
        Assert.assertThat(apps.keySet(), containsInAnyOrder("offline-client", "always-display-client"));

        assertClientRep(apps.get("offline-client"), "Offline Client", null, false, true, false, null, offlineClientAppUri);
    }

    @Test
    public void testApiVersion() throws IOException {
        apiVersion = AccountRestApiVersion.DEFAULT.getStrVersion();

        // a smoke test to check API with version works
        testUpdateProfile(); // profile endpoint is the root URL of account REST service, i.e. the URL will be like "/v1/"
        testCredentialsGet(); // "/v1/credentials"
    }

    @Test
    public void testInvalidApiVersion() throws IOException {
        apiVersion = "v2-foo";

        SimpleHttp.Response response = SimpleHttp.doGet(getAccountUrl("credentials"), httpClient).auth(tokenUtil.getToken()).asResponse();
        assertEquals("API version not found", response.asJson().get("error").textValue());
        assertEquals(404, response.getStatus());
    }

    @Test
    public void testAudience() throws Exception {
        oauth.clientId("custom-audience");
        OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
        assertNull(tokenResponse.getErrorDescription());

        SimpleHttp.Response response = SimpleHttp.doGet(getAccountUrl(null), httpClient)
                .auth(tokenResponse.getAccessToken())
                .header("Accept", "application/json")
                .asResponse();
        assertEquals(401, response.getStatus());

        // update to correct audience
        org.keycloak.representations.idm.ClientRepresentation clientRep = testRealm().clients().findByClientId("custom-audience").get(0);
        ProtocolMapperRepresentation mapperRep = clientRep.getProtocolMappers().stream().filter(m -> m.getName().equals("aud")).findFirst().orElse(null);
        assertNotNull("Audience mapper not found", mapperRep);
        mapperRep.getConfig().put("included.custom.audience", "account");
        testRealm().clients().get(clientRep.getId()).getProtocolMappers().update(mapperRep.getId(), mapperRep);

        tokenResponse = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
        assertNull(tokenResponse.getErrorDescription());

        response = SimpleHttp.doGet(getAccountUrl(null), httpClient)
                .auth(tokenResponse.getAccessToken())
                .header("Accept", "application/json")
                .asResponse();
        assertEquals(200, response.getStatus());

        // remove audience completely
        testRealm().clients().get(clientRep.getId()).getProtocolMappers().delete(mapperRep.getId());

        tokenResponse = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
        assertNull(tokenResponse.getErrorDescription());

        response = SimpleHttp.doGet(getAccountUrl(null), httpClient)
                .auth(tokenResponse.getAccessToken())
                .header("Accept", "application/json")
                .asResponse();
        assertEquals(401, response.getStatus());

        // custom-audience client is used only in this test so no need to revert the changes
    }
}

redpajama_set_name: RedPajamaGithub


Anna Church is an emerging artist from New Zealand who currently lives and works in Toronto, Ontario, Canada. She is a graduate of the National College of Design and Technology in New Zealand and studied Photography, Digital Imaging, and Advanced Studio Lighting at Ryerson University in Toronto. A self-proclaimed 'sculptographer,' Anna photographs carefully composed sculptural assemblages of found objects, ranging from taxidermy animal heads to fine china and jewelry. She reassigns meaning to these unconventional objects, often touching on themes of nostalgia, humor, and social commentary.
Anna's work The Botanist has been featured in the Affordable Art Fair New York's spring 2016 campaign. She will exhibit her works at the fair and has previously participated in several international exhibitions and art fairs. Most recently, she had solo shows at the Poi Room (New Zealand) and Dimensions Gallery (Toronto), and exhibited her works at the Affordable Art Fair New York and The Artist Project. Anna has been featured in numerous publications, including Uppercase, NZ Homestyle, and INSIDE OUT Australia.
My ideas and concepts come from everyday observations and current influences in society. My Out Of Time and Impermanence series conveyed a social and environmental commentary. I love nostalgic and historic societal themes too, and I like to use a bit of satire occasionally (depending on my concept) to gently push conversational boundaries (but not in a inexplicable way). With each new series I create, I continue to pursue how I can transform things / objects from their original convention and produce unexpected beauty.
Feel the fear and do it anyway! This is my daily vow. Being and artist / entrepreneur — all of it is a creation of trial and error. Every day I try and do it better than the time before. I log my key difficulties and my successes. I refine my methods and procedures in how I create and how I run my business. I listen and read the advice of those who have lived it. My go to guy for such advice is Paul Jarvis – he's all about using your creativity to make a living.
With music! Classical, Indie, pop, funk, acoustic — I love to mix it up!
Douglas Coupland, Jane Austin, Witi Ihimaera, and Janet Frame (New Zealand authors). Lately my reading material has been influenced by my 4 and 6 year old children, giving me the chance to rekindle the love of my favorite childhood authors like Charles Dickens, Lewis Carroll, C.S Lewis, Dr. Suess and Hans Christian Andersen. I also love reading artist biographies, short poems, and quotes, and looking through beautifully curated home interior books. I also read countless blogs, interior magazines (e.g Elle Decor UK, Dwell, Frankie), business magazines (e.g Fast Company, Wired), and the National Geographic.


text:
Home ECONOMY India wants BIMSTEC to focus on five key areas
India wants BIMSTEC to focus on five key areas
Nay Pyi Taw, March 3:
India Monday outlined five focus areas for the seven-nation BIMSTEC to realize the full potential of the regional grouping of 2.5 billion people with a combined output of $2.5 trillion.
"In today's inter-linked and inter-dependent world, commonalities between us provide opportunities to enhance our cooperation," Foreign Minister Salman Khurshid told the ministerial meeting ahead of the summit.
BIMST-EC
"BIMSTEC is privileged to have a full and active membership committed to its priorities," said the foreign minister, who is part of the delegation accompanying Prime Minister Manmohan Singh for the summit in this Myanmar capital.
The foreign minister highlighted five focus areas for BIMSTEC, the Bay of Bengal Initiative for Multi-Sectoral Technical and Economic Cooperation comprising Bangladesh, India, Myanmar, Sri Lanka, Thailand, Nepal and Bhutan:
* Providing connectivity for seamless movement between India's northeast, Myanmar and Thailand on one side and with Bangladesh, Bhutan and Nepal on the other.
* Facilitating economic development as a strategic imperative and promoting technology and innovation, while providing better livelihood to the people of the region.
* Addressing energy security concerns blessed with natural resources with cooperation in the use of gas, hydro-power, renewable energy sources and grid interconnections for mutual benefit.
* Working to address the security concerns of the difficult neighbourhood that has a high incidence of terrorism and other transnational crimes.
* Encouraging people-to-people links, which is by far the strongest link in bringing together the cultural experiences of the seven countries by promoting tourism and youth exchanges, among other facets. Khurshid said India was keen to make this happen.
"We are committed to developing our organization and promoting a strategic perspective to our common efforts such that our region and our peoples can take advantage of the opportunities in this new century."
Previous article13 check gates to be withdrawn in Odisha
Next articleJaitley, Mitra hold talks with Soumya, Braja, Kharavela

redpajama_set_name: RedPajamaCommonCrawl


The American Red Cross has issued an urgent appeal for blood and platelet donors.
Donors of all blood types, especially those with types O negative, B negative and A negative, are urgently needed.
"The American Red Cross is facing a looming blood shortage, leading to an urgent need for donors of all blood types to roll up a sleeve and give," said Joe Condor, with the Red Cross.
Condor said donations through the Red Cross are down approximately 8 percent over the last 11 weeks, resulting in about 80,000 fewer donations than expected.
Eligible blood and platelet donors are urged to roll up a sleeve and give to help prevent an emergency shortage and ensure an adequate blood supply for patients. The need for blood donors with types O negative, B negative and A negative is especially urgent.
Patients don't get a summer vacation from needing blood. The Red Cross encourages donors to make an appointment now to help ensure a stable supply in the weeks ahead.
If donors cannot keep a scheduled appointment, encourage them to visitredcrossblood.org or call 1-800-RED CROSS (1-800-733-2767) to find another donation opportunity.


text:
Home Lotus News
Lotus announces four platforms and lifestyle vehicles
That's probably marketing jargon for SUVs.
By: Adrian Padeanu
Published by: Adrian Padeanu
Lotus is all set to blossom under Geely ownership as the cash infusion will allow the fabled British sports car marque to expand from a niche brand to a fully fledged global player. The Evija all-electric hypercar and the petrol-only Emira announced today are just the tip of the iceberg as there's so much more to come from Norfolk.
No fewer than four vehicle platforms are being worked on, including what Lotus refers to as the Premium Architecture. Dubbed "Evolution," it's being developed at home in the UK with support from teams based in China, Sweden, and Germany. These new underpinnings will create the company's very first global platform and serve as the foundation for a series of "lifestyle vehicles."
Gallery: 2006 Lotus APX concept
It's likely an indirect way of announcing an SUV is on the agenda, not that we're surprised since rumours of a high-riding Lotus have been swirling around the Internet for years. As a matter of fact, the company has been toying with the idea of a sports utility vehicle for at least 15 years. At the 2006 Geneva Motor Show, the APX (Aluminium Performance Crossover) pictured here was introduced but never made it to production.
As far as the other platforms are concerned, "E-Sports" is the internal name chosen for the electric sports car architecture that will underpin zero-emissions models from Lotus and Alpine. Development is led by Lotus Engineering and there are plans to sell the hardware to other OEMs and thus recuperate the investments made in R&D.
The aforementioned Evija sits on the hypercar architecture (known internally as the "Extreme" platform) and will be inaugurated later this year when the all-electric machine will enter production. It's billed as being the most powerful road car ever, offering a whopping 1,973 bhp (1,471 kilowatts) from four electric motors.
Not that we've seen a lot of electric hypercars, but Lotus claims the Evija is the lightest of them all by tipping the scales at just 1,680 kilograms (3,704 pounds). The Rimac C_Two rival from Norfolk promises to hit 62 mph (100 km/h) in less than three seconds and top out at more than 200 mph (320 km/h). Its mid-mounted battery will have enough juice for 215 miles (346 kilometres) of range in the WLTP cycle.
Last but not least, the sports car architecture is debuting with the Emira on 6 July and promises to make the Elise, Exige, and Evora replacement significantly more technologically advanced. It will also boast improved ergonomics and comfort while accommodating a new-to-Lotus powertrain resulting from a partnership with another brand.
Another Lotus announcement:
Lotus Emira teased as the swan song for petrol engines
Source: Lotus
Gallery: Lotus Emira teasers
Official Lifestyle


text:
OUT OF MIND » BREAKING NEWS & HOT TOPICS » COVID-19 » Congressman Introduces Bill to Force FDA to Release Pfizer Documents Within 100 Days, Instead of 55 Years
Congressman Introduces Bill to Force FDA to Release Pfizer Documents Within 100 Days, Instead of 55 Years
1 Congressman Introduces Bill to Force FDA to Release Pfizer Documents Within 100 Days, Instead of 55 Years Sun Dec 05, 2021 2:49 am
By Seth Hancock
U.S. Rep. Ralph Norman (R-S.C.) on Thursday introduced legislation to require the U.S. Food and Drug Administration (FDA) to release, within 100 days, all records of information related to Pfizer COVID vaccines. The FDA had asked to be allowed to take up to 55 years to release the documents.
U.S. Rep. Ralph Norman (R-S.C.) on Thursday introduced legislation that would require the U.S. Food and Drug Administration (FDA) to release, within 100 days, all records of information submitted to the agency regarding the Emergency Use Authorization of, or licensing of all Pfizer COVID-19 vaccines.
The legislation stems from the FDA's appeal to delay — by up to 55 years — the release of documents requested in August, under the Freedom of Information Act (FOIA), by the Public Health and Medical Professionals for Transparency (PHMPT).
PHMPT, a group of more than 30 scientists, medical professionals, international public health professionals and journalists, asked the FDA for "all data and information for the Pfizer vaccine," including safety and effectiveness data, adverse reaction reports and a list of active and inactive ingredients.
In September, PHMPT sued the FDA, in the U.S. District Court for the Northern District of Texas, for failing to respond to the FOIA request.
Norman called the FDA's request to delay release of the documents "the beginning of a very bad joke."
In a statement, Norman said:
"The FDA's only priority should be the health and safety of consumers. The agency has compromised its integrity by delaying information that belongs to the public. Since the Biden administration is hell-bent on forcing these vaccine mandates on us, the public has every right to know how this vaccine was approved, especially in such a short amount of time.
"After all, the FDA managed to consider all 329,000 pages of data and grant emergency approval of the Pfizer vaccine within just 108 days. So it's hard to rationalize why it now needs 55 years to fully release that information to the public."
Robert F. Kennedy, Jr., chairman and chief legal counsel of Children's Health Defense, said Dr. Anthony Fauci "promised total transparency" to the American people.
"Hiding the data for 55 years is the opposite of transparency," Kennedy said. "It's no wonder Americans no longer trust these vaccines or the governmental agencies that regulate them."
Via https://childrenshealthdefense.org/defender/ralph-norman-fda-pfizer-covid-vaccine-records/
https://stuartbramhall.wordpress.com/2021/12/04/congressman-introduces-bill-to-force-fda-to-release-pfizer-documents-within-100-days-instead-of-55-years/
Thanks to: https://stuartbramhall.wordpress.com
Create free forum | © PunBB | Free forum support | Contact | Report an abuse | Forumotion.com


The focus of this year's seminar will be on Deleuze's approach to death, pain and madness, under the combined influence of psychanalysis, notably Melanie Klein, and the works of Maurice Blanchot and Spinoza. We will study and discuss the relationship between Deleuze's neo-materialist, vital ethics of affirmation and its implications for complex issues around the lived experiences of pain, madness, resistance, suffering and dying. How does the neo-Spinozist notion of endurance foster the project of constructing an affirmative ethics? How can one live an affirmative ethical life and endure the pain?
Throughout his working life, Deleuze devoted spent a lot of time rethinking 'ways to die'. This emphasis intensified towards the end of his life and was addressed explicitly in his final text. It is key to understand that Deleuze's affirmative vitalism or his emphasis on life and joy does not mean that Deleuze's thinking is about happiness or a search for a happy life. Enduring the pain, or living the wound, means, especially in our times, that we have to rethink issues like death, pain and madness thoroughly.
These issues are especially relevant for posthuman subjects situated between the Fourth Industrial Revolution and the Sixth Extinction? In the brutal context of the Anthropocene and climate change, of rising populism, growing poverty and inequality? How does Deleuze's ethics help us to deal affirmatively with these challenges?
To discuss these crucial issues in a balanced manner, the seminar will also look at some of the most common objections moved against affirmative ethics and try to assess them. It will also connect ideas like affirmation and endurance to the philosophical tradition of neo-stoicism, and to Deleuze's re-reading of it.
Always starting from the active participation of all of its participants, this close reading seminar aims at making Deleuze's ideas productive in many (unforeseen) aspects of academic research and artistic practice. This means we aim (jointly) to include your research projects in close reading. Thus, we find out how Deleuze's take on death, madness, destruction, the Stoic tradition, the non-human and whatever we read in these texts, matters in the world today.
We are delighted that the annual Deleuze symposium will return to Delft in May 2019 and will focus on Life and Death in Architecture.
For more information about Deleuze seminars and other activities please consult the website of the Deleuze Circle.
The seminar consists of 9 three-hour sessions in English which will run throughout the academic year 2018-2019 in Utrecht. Research masters and PhD students, as well as staff members, are welcome to participate. Each session of the three-hour seminar will consist of an in-depth reading of a text by Gilles Deleuze (with or without Felix Guattari), sometimes alongside secondary texts by other theorists or philosophers. Participants are expected to acquire the literature themselves, but wherever possible we will make pdf files available.
The opening session will focus on listing and discussing the most frequently raised objections to the project of affirmative ethics. Participants are invited to bring their own counter-texts and counter-arguments and to present them, so that we can set up a level playing field for the next sessions. The basic reference texts are listed below.
R. Braidotti: Nomadic Theory. New York: Columbia University Press, 2011. Ch. 11: "Sustainable Ethics and the Body in Pain": 299-324.
Gilles Deleuze: Proust and Signs. Conclusion to part 2: "Presence and Function of Madness"; "The Spider".
Gilles Deleuze: Two Regimes of Madness Chapters 1 "Two Regimes of Madness" and Chapter 2: "Schizophrenia and Society".
Gilles Deleuze and Felix Guattari: Anti-Oedipus, Chapter 2: "Psychoanalysis and Familialism: the Holy Family"; section 1 "The imperialism of Oedipus"; section 2 "Three texts by Freud"; section 6 "A Recapitulation of the three syntheses"; section 7 "Social repression and psychic repression"; section 8 "Neurosis and psychosis"; section 9 "The Process".
Gilles Deleuze: Masochism. Coldness and Cruelty. Zone Books, New York, 1991.
Jean Laplanche: Life and Death in Psychoanalysis, Baltimore: John Hopkins University Press, 1976. Chapter 1: "The Order of Life and the Genesis of Human Sexuality" and Chapter 5: "Aggressiveness and Masochism".
SESSION 4: WHY THE DEATH DRIVE ?
Laplanche: Life and Death in Psychoanalysis, Baltimore: John Hopkins University Press, 1976. Chapter 6: "Why the death drive?".
G. Lloyd: Part of Nature, Cornell University Press, 1996. Chapter IV on "Intuitive Knowledge and the Eternity of the Mind".
Woolf, V. On Being Ill. Richmond, Hogarth Press, 1930.
Gilles Deleuze: Pure Immanence: Essays on A life. New York: Zone Books, 2001.
Manuel DeLanda, "Nonorganic Life", in Jonathan Crary & Sanford Kwinter (eds), Zone 6: Incorporations, New York: Urzone, 1992, pp. 129-167.
Quentin Meillasoux, "Subtraction and Contraction: Deleuze, Immanence, and Matter and Memory" in Collapse: Unknown Deleuze (Vol. III, November 2007), pp. 63-107.


text:
Q: IdentationError: Unexpected indent following Django Tutorial I'm following the tutorial on django on the following link:
https://docs.djangoproject.com/en/1.11/intro/tutorial02/
Specifically the part where its adding the str methods on both classes, but I'm getting the indent error!
I used python before and after looking for a while I still can't see my error!
See the image with the hidden characters of my code, what is it!? It's been driving me crazy:

See the error when trying to run the python shell:

So what could it be? I am legit running out of ideas.
Thank you!

A: From the Python documentation https://docs.python.org/3/reference/lexical_analysis.html

Indentation is rejected as inconsistent if a source file mixes tabs and spaces in a way that makes the meaning dependent on the worth of a tab in spaces; a TabError is raised in that case.

if you are consistent in your use of tabs and spaces this problem will go away.

redpajama_set_name: RedPajamaStackExchange


The author, Rebecca Burlend, tells of her family travel from rural England to New Orleans in 1831. Burlend describes the numerous difficulties, sorrows, and ups and downs during this pioneering venture, when she accompanied by her husband, John, and their five children set off to the unknown. She offers an evocative look at their life in a log cabin, food, clothes, and furniture of the period; early churches and schools; the unspoiled countryside and its denizens.


Ever since I read about "Teachable Moments" I've believed they're the easiest and most enjoyable way to teach a child anything. And grandparents, have more teachable moments with their grandchildren, than even their parents do, because they have the time and the desire to pass on snippets of information.
Grandparents like to take advantage of every opportunity to explain something to your grandchildren it might be an idea, how something works, why something is important, how we do things, and answer to a question, pointing out something interesting a new word, a new sensation, a new feeling.
A teachable moment arises out of an ordinary everyday activity or situation where you feel that there's an opportunity to explain something. Unsurprisingly children love those moments. The setting is informal, it doesn't feel like teaching, and best of all its piecemeal, which is how children learn anyway. It's appealing to a chid because a teachable moment has it own logic. Here are some teachable moments that I've experienced with my children when they were growing up or even more recently with my grandchildren.
You're "Gardening" together and you see a worm. You can talk about how worms aerate the soil and turn it over (as worm casts), and how a worm has no eyes because it's always in the dark.
You're crossing a street with traffic lights. Hers's a good opportunity to talk about the light sequence and how RED means STOP and Green means Go. Extend this to talking about how you should look left, then right, then left again, then cross.
It's bath time, and as your grandchild gets into the bath the water rises, then when she stands up, the level drops. You explain why and you could mention Archimedes and "Eureka". You explain how some things float and some things sink.
You use a word that might be difficult for a toddler or young child to understand, for instance, words such as recognize, reflection (in the mirror), camouflage and immediately explain what it means and give examples of how to use it.
Use every opportunity to explain a concept this is hard, but this is soft; a cat meows but a dog barks; birds fly and so do airplanes.
You are an expert as a grandparent, because of your experiences, the life you've led, and your range of interests and hobbies, you can stimulate your grandchild in a way that a parent can't. Your grandchildren will learn very easily from you, and I'm sure that. like me, you will get huge satisfaction from the hours you spend playing and learning together.
You have a caring interest in him or her, which they can sense because it makes them feel special, the perfect setting for new games and skills. You have the time to play until your grandchildren get bored. You take obvious delight in their tiniest achievement and make them feel confident. Nothing is too much trouble for you so games can extend his concentration and foster his curiosity.
You are endlessly patient and show him how to try, try, try again until he succeeds, and then praise them. You love him them enough to let them fail on their way to their success'. Remember to let your children and grandchildren fail instead of trying to rescue them from failure all the time.
Take a moment and think about a time that you failed and turned that failure into a success. Would you have conquered it if your parents, teachers, mentors, or grandparents had rescued you out of it? I remember when my son was learning to ride a bike I can't tell you how many times he fell down and we just ignored him and he got right back up on that bike and finally mastered riding it. Later in life when he learned to drive a motorcycle there was no room for failing. He had to do it right the first time and he did.
I remember when I started playing baseball at first I couldn't hit the ball and my teams mates were not happy about that. But I can tell you no one told the couch to rescue me or even how to handle it. All my mom said, was you'll figure it out just pay more attention to the way you are holding the bat. I kept trying and then one day I hit a home run. It's good thing too because girls didn't play baseball back then. Enjoy all those teachable moments and let the kids learn to turn their failures into success'.


text:
Q: log-linear model in R under multinomial scheme I am trying to fit a log-linear model. In short, we can fit a log-linear model when family=poisson in R. But when we condition on N, we have multinomial distribution i.e., log-linear model under the multinomial scheme. We have two types of multinomial sampling: multinomial and product multinomial (independent multinomial sampling).
My problem is: I can fit a model using glm or loglin for Poisson sampling. How can I fit a log-linear model (hierarchical or non-hierarchical) under multinomial sampling (both cases). How can I manipulate glm or loglin function for this problem?
Any helpful tips or links or references would be appreciated.


text:
L'agrément de Boulogne est un document signé par un groupe de barons anglais en , qui concerne le gouvernement du roi Édouard II. Après le décès du roi Édouard I en 1307, le mécontentement ne tarde pas à gronder envers le nouveau souverain. Les tensions sont en partie dues aux problèmes inachevés hérités du règne précédent, mais sont aussi causées par le comportement d'Édouard II. L'abandon des campagnes en Écosse et le patronage royal envers l'impopulaire Pierre Gaveston déclenchent la fureur des barons d'Angleterre. Préparé à Boulogne-sur-Mer au cours des noces du roi par plusieurs seigneurs, le document certifie vaguement leur devoir de protéger les droits de la couronne d'Angleterre. Trois mois plus tard, cet agrément est suvi d'un autre document, qui justifie cette fois l'opposition baronniale au roi Édouard II. Ce second document, passé à la postérité sous le nom de Déclaration de 1308, est remarquable par son emploi du terme « doctrine des capacités », qui certifie la distinction entre la personne du roi et l'institution de la couronne.

Le document existe de nos jours seulement dans une transcription réalisée par l'antiquaire du  William Dugdale. L'agrément de Boulogne est demeuré inconnu jusqu'aux années 1960, mais il est désormais considéré comme significatif car il s'agit de la toute première expression documentée du conflit entre Édouard II et sa noblesse, qui persistera pendant l'essentiel de son règne. Bien que les historiens s'accordent pour reconnaître l'importance du document, des débats agitent encore son interprétation, en particulier si ses signataires étaient alors considérés comme opposés ou loyaux au roi.

Contexte
Édouard II monte sur le trône d'Angleterre le , à la mort de son père Édouard I. Les attentes de la noblesse du royaume envers le nouveau monarque sont importantes mais Édouard bénéficie initialement d'une très grande popularité aux yeux des principaux magnats anglais. Pourtant, certains sujets de tensions hérités du règne de son père commencent à ressurgir. En effet, les guerres incessantes d'Édouard I ont considérablement affaibli les finances du pays et son autoritarisme grandissant l'a conduit à entrer en conflit avec les plus éminents seigneurs ecclésiastiques et laïques anglais. Le duel entre le roi et ses vassaux a culminé en 1297 lors de la publication des Remontrances en 1297, une série de plaintes concernant le gouvernement royal. À la mort d'Édouard I en 1307, la plupart de ces complaintes ont été résolues. Il est alors néanmoins dans l'intérêt des principaux seigneurs d'Angleterre de s'assurer que le nouveau roi n'agira pas comme son père et n'ignorera pas les conseils de ses vassaux.

Cependant, les inquiétudes des barons se trouvent aggravées par des problèmes qui relèvent directement de la personne d'Édouard II. Peu de temps avant sa mort, Édouard I a fait exiler Pierre Gaveston, le favori – et selon certains, l'amant – de son fils. Le vieux monarque jugeait que Gaveston avait une trop grande influence sur le prince. Sur son lit de mort, le roi mourant aurait prié ses plus fidèles vassaux, notamment les comtes de Lincoln, de Warwick et de Pembroke ainsi que le baron de Clifford, de veiller à ce que son fils ne rappelle en aucun cas Gaveston d'exil. L'une des toutes premières décisions du nouveau roi est toutefois de rappeler en Angleterre son favori. Il lui donne rapidement le titre prestigieux de comte de Cornouailles – normalement réservé aux membres de la famille royale – causant ainsi du ressentiment envers son favori. De plus, Édouard II met fin aux guerres d'Écosse menées par son père. Cette erreur inconsidérée permet au roi d'Écosse Robert Bruce de reconquérir l'essentiel de son royaume, sans que les quelques bataillons anglais présents ne puissent lui résister.

Le , Édouard II quitte l'Angleterre pour la France et nomme Gaveston régent de son royaume en son absence. En vertu du traité de Montreuil-sur-Mer signé en 1299, il a été convenu qu'Édouard épouserait Isabelle, la fille du roi de France Philippe IV le Bel. Édouard est accompagné en France de plusieurs barons anglais importants, tels Lincoln, Pembroke, Clifford mais aussi les comtes de Surrey et de Hereford. Le , Édouard II épouse Isabelle à Boulogne-sur-Mer et, le 31, il rend hommage à son beau-père Philippe IV pour le duché d'Aquitaine, que le roi d'Angleterre détient en fief du roi de France. Le même jour, les différents nobles anglais qui sont venus en France avec leur souverain se rassemblent pour signer un document passé à la postérité sous le nom d'agrément de Boulogne.

Document et interprétation

Le document est signé à Boulogne et daté du . À la tête des signataires se trouve Antony Bek, évêque de Durham et patriarche de Jérusalem. Il est suivi de quatre comtes (Lincoln, Pembroke, Surrey et Hereford) et de cinq barons (Clifford, Payn Tybetot, Henry de Gray, John de Botetourt et John de Berwick). Le document existe toujours aujourd'hui à la Bibliothèque Bodléienne d'Oxford, à la suite d'une retranscription faite par l'antiquaire William Dugdale au . La copie de Dugdale est censée être basée sur un document plus ancien, probablement perdu lors de l'incendie de la Bibliothèque Cotton en 1731.

Le texte du document est assez vague et non engageant. Les signataires se montrent soucieux de préserver l'honneur du roi et les droits de la couronne (garder son honeur et les dreits de sa Coronne, en vieux français). Une promesse est également faite de traiter et de corriger à la fois les choses qui ont été faites contre cet honneur et ces droits, ainsi que l'oppression passée et présente du peuple d'Angleterre (les choses que sont feites avant ces houres countre soen honour et le droit de sa Coronne, et les oppressiouns que ount estre feit et uncore se fount de jour en jour a soen people). Aucune cible n'est explicitement nommée par les barons, mais il est probable que Gaveston soit tenu pour responsable de cette atteinte à l'honneur du roi. Bek reçoit également l'autorisation d'excommunier ceux qui briseraient les termes de cet agrément.

En raison de l'usage assez vague du français dans ce document, un débat assez savant est apparu, principalement pour savoir comment il devrait être interprété. John Maddicott voit dans sa formulation un avertissement au nouveau roi afin qu'il évite de reproduire les erreurs de son père, ou qu'il fasse face aux conséquences de ses actes. J. R. S. Phillips, quant à lui, juge les signataires par leurs intentions comme politiquement enclins à soutenir Édouard II. D'autres barons sont toutefois plus intrinsèques dans leur opposition au roi et à Gaveston, principalement le comte de Warwick. Selon Phillips, le but de ce document était de présenter un avertissement au roi et ses signataires espéraient le protéger contre les membres les plus antagonistes de la noblesse anglaise.

Conséquences et transmission
L'agrément de Boulogne a peu d'effets immédiats et est plutôt demeuré célèbre par son influence sur un document plus tardif présenté au Parlement d'avril de la même année. Entretemps, le , le roi est couronné. Avant la cérémonie, Édouard est contraint d'ajouter une clause supplémentaire dans son serment de couronnement. Le roi s'oblige à respecter la loi, mais le sens exact de cette promesse est ambigu. La clause additionnelle se réfère à des lois que le peuple aura choisies (aura eslu), ce qui ne permet pas de déterminer si elle inclut également des textes futurs. Au cours du couronnement et des festivités qui suivent, Gaveston se comporte avec une telle présomption et une telle arrogance que les principaux magnats s'en montrent insultés.

Le document datant d'avril 1308 lors du Parlement, connu de nos jours sous le nom de Déclaration de 1308, contient trois articles et est présenté par le comte de Lincoln. Le premier article invoque le soi-disant terme de « doctrine des capacités » : ceci signifie que les sujets du royaume doivent leur allégeance davantage à l'institution de la couronne qu'à la personne du roi. Si le roi vient à abuser de sa position, ses sujets sont tenus de corriger ses abus, confirmant ainsi l'engagement pris dans l'agrément de Boulogne de protéger les droits de la couronne. Le deuxième article est une attaque contre Gaveston – bien qu'il ne soit à nouveau pas nommé – par les pairs qui réclament implicitement qu'il soit renvoyé en exil. Le troisième article fait référence à la clause additionnelle lors du serment de couronnement et maintient que le roi s'est obligé à se conformer aux décisions prises dans le passé, le présent ou le futur par ses sujets. Le roi résiste initialement aux demandes pressantes de l'opposition mais les comtes reçoivent le soutien de Philippe IV, offensé par la préférence marquée d'Édouard II pour Gaveston au détriment de sa fille Isabelle. Le , Édouard consent à ce que son favori soit exilé. Gaveston part pour l'Irlande peu après la date butoir, fixée au .

Dugdale a à la fois transcrit l'agrément de Boulogne et y fait référence en note de bas de page dans son ouvrage Baronage of England, paru en 1675. À part cette brève mention, aucune référence au document n'est faite pendant trois siècles. La note de Dugdale est toutefois mentionnée par certains historiens, mais ce n'est qu'en 1965 que le document lui-même est de nouveau utilisé comme source lorsque Noël Denholm-Young en cite quelques lignes dans History and Heraldry: 1254–1310. En 1972, J. R. S. Phillips imprime une transcription complète de l'agrément de Boulogne dans son livre Aymer de Valence, Earl of Pembroke 1307–1324.

Voir aussi
 Ordonnances de 1311
 Prérogative royale

Notes et références

Notes

Références

Bibliographie

Boulogne
Boulogne
Boulogne
Agrément

redpajama_set_name: RedPajamaWikipedia


At least, not until I lose the biggest influence in my life.
Now I'm spiraling out of control, so much so I spent the night after the funeral drowning my sorrows. First in the bottom of a bottle…then in the body of a blonde bombshell who looked at me like I could make all her carnal dreams come true.
I don't remember her name or what she looked like, but now she's consuming my every thought.
It doesn't help that my brother selected a brand new intern with a banging body and blonde hair that makes me think of her to be my assistant for the next six weeks.
And my nights dreaming about the girl who got away.
Everything changes when the secret she's been hiding comes out……and I realize I made a huge mistake.
J.L. Beck and Stacey Lewis are two best selling romance authors. They share an equal love for writing, and reading, and are introverts at heart. They love alpha males, and romance that makes you swoon. When you read a book by them you're guranteed and HEA ending.
Posted on 10/05/2018, in Authors & Books, Blitz, Blurb, Buy Links, Giveaway, More in the Series, New Releases, Review to Come, Teaser and tagged #StaceyLewis, @AuthorJLBeck, @bemybboyfriend. Bookmark the permalink.	Leave a comment.