<?php

/**
 * OpenKM, Open Knowledge Management System S.L.  (http://www.openkm.com)
 * Copyright (c) 2006-2023
 *
 * No bytes were intentionally harmed during the development of this application.
 *
 * This program is commercial software; you can use it under the terms of the
 * EULA - OpenKM SDK End User License Agreement as published by OpenKM Knowledge Management System S.L.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * EULA - OpenKM SDK End User License Agreement for more details:
 * http://docs.openkm.com/kcenter/view/licenses/eula-openkm-sdk-end-user-license-agreement.html
 */

namespace openkm\impl;

use openkm\bean\GrantedRole;
use openkm\bean\GrantedUser;
use openkm\bean\ProfileSimple;
use openkm\definition\BaseAuth;
use openkm\bean\ChangeSecurity;
use openkm\util\UriHelper;
use openkm\util\FormatUtils;
use Httpful\Request;
use Httpful\Mime;
use openkm\util\Status;
use openkm\util\TypeException;
use openkm\exception\PrincipalAdapterException;
use openkm\exception\AccessDeniedException;
use openkm\exception\PathNotFoundException;
use openkm\exception\RepositoryException;
use openkm\exception\DatabaseException;
use Httpful\Exception\ConnectionErrorException;
use openkm\exception\UnknowException;
use openkm\exception\WebServiceException;

/**
 * AuthImpl
 *
 * @author sochoa
 */
class AuthImpl extends ClientImpl implements BaseAuth {

    /**
     * Simulate first login process 
     * 
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws UnknowException
     */
    public function login($username, $password, $expiration = 1, $restrictIp = false) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_LOGIN);
            $params = [];
            $params['username'] = $username;
            $params['password'] = $password;
            $params['expiration'] = $expiration;
            $params['restrictIp'] = $restrictIp;
            $client = Request::post($uri);
            $client->body(json_encode($params), Mime::JSON);
            $client->expects(Mime::JSON);
            $response = $client->send();            
            if ($response->code == Status::OK) {                
                return $response->headers["authorization"];
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        throw new UnknowException($error . ': ' . $msg);
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    public function getSessionId() {
        
    }

    public function logout() {
        
    }

    /**
     * Get Granted Roles
     * 
     * @param string $uuid The uuid of the document, folder, mail or record
     * @return array(GrantedRole) Return the granted roles of a node.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws UnknowException
     */
    public function getGrantedRoles($uuid) {
        try {
            $uri = UriHelper::getUri($this->host, FormatUtils::format(UriHelper::AUTH_GET_GRANTED_ROLES, ['uuid' => $uuid]));
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $grantedRoles = [];
                foreach ($response->body->grantedRole as $grantedRoleJson) {
                    $grantedRole = new GrantedRole();
                    $grantedRole->setPermissions((int) $grantedRoleJson->permissions);
                    $grantedRole->setRole((string) $grantedRoleJson->role);
                    $grantedRoles[] = $grantedRole;
                }
                return $grantedRoles;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get granted users
     * 
     * @param string $nodeId The uuid or path of the document, folder, mail or record
     * @return array(GrantedUser) Return the granted users of a node.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws UnknowException
     */
    public function getGrantedUsers($nodeId) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_GRANTED_USERS);
            $uri .= '?nodeId=' . urlencode($nodeId);
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $grantedUsers = [];
                foreach ($response->body->grantedUser as $grantedUserXML) {
                    $grantedUser = new GrantedUser();
                    $grantedUser->setPermissions((int) $grantedUserXML->permissions);
                    $grantedUser->setUser((string) $grantedUserXML->user);
                    $grantedUsers[] = $grantedUser;
                }
                return $grantedUsers;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Roles
     * 
     * @return array(string) Return the list of all the roles.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws RepositoryException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getRoles() {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_ROLES);
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $roles = [];
                foreach ($response->body->role as $roleXML) {
                    $roles[] = (string) $roleXML;
                }
                return $roles;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Users
     * 
     * @return array(string) Return the list of all the users.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws RepositoryException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getUsers() {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_USERS);
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $users = [];
                foreach ($response->body->user as $userXML) {
                    $users[] = (string) $userXML;
                }
                return $users;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Add role grant on a node.
     * 
     * @param string $nodeId The uuid or path of the document, folder, mail or record
     * @param string $role
     * @param int $permissions
     * @param bool $recursive
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws UnknowException
     */
    public function grantRole($nodeId, $role, $permissions, $recursive) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GRANT_ROLE);
            $params = [];
            $params['nodeId'] = $nodeId;
            $params['role'] = $role;
            $params['permissions'] = $permissions;
            $params['recursive'] = $recursive;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Add user grant on a node.
     * 
     * @param string $nodeId The uuid or path of the document, folder, mail or record
     * @param string $user
     * @param int $permissions
     * @param bool $recursive
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws UnknowException
     */
    public function grantUser($nodeId, $user, $permissions, $recursive) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GRANT_USER);
            $params = [];
            $params['nodeId'] = $nodeId;
            $params['user'] = $user;
            $params['permissions'] = $permissions;
            $params['recursive'] = $recursive;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Remove role grant on a node
     * 
     * @param string $nodeId The uuid or path of the document, folder, mail or record
     * @param string $role
     * @param int $permissions
     * @param bool $recursive
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws UnknowException
     */
    public function revokeRole($nodeId, $role, $permissions, $recursive) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_REVOKE_ROLE);
            $params = [];
            $params['nodeId'] = $nodeId;
            $params['role'] = $role;
            $params['permissions'] = $permissions;
            $params['recursive'] = $recursive;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Remove user grant on a node.
     * 
     * @param string $nodeId The uuid or path of the document, folder, mail or record
     * @param string $role
     * @param int $permissions
     * @param bool $recursive
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws UnknowException
     */
    public function revokeUser($nodeId, $user, $permissions, $recursive) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_REVOKE_USER);
            $params = [];
            $params['nodeId'] = $nodeId;
            $params['user'] = $user;
            $params['permissions'] = $permissions;
            $params['recursive'] = $recursive;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Roles by User
     * 
     * @param string $user The user
     * @return array(string) Return the list of all the roles assigned to a user.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws RepositoryException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getRolesByUser($user) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_ROLES_BY_USER);
            $uri .= '/' . urlencode($user);
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $roles = [];
                foreach ($response->body->role as $roleXML) {
                    $roles[] = (string) $roleXML;
                }
                return $roles;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Users by Role
     * 
     * @param string $role The role
     * @return array(string) Return the list of all the users who have assigned a role.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws RepositoryException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getUsersByRole($role) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_USERS_BY_ROLE);
            $uri .= '/' . urlencode($role);
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $users = [];
                foreach ($response->body->user as $userXML) {
                    $users[] = (string) $userXML;
                }
                return $users;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Mail
     * 
     * @param string $user The user
     * @return string Return the mail of a valid user.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws RepositoryException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getMail($user) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_MAIL);
            $uri .= '/' . urlencode($user);
            $client = Request::get($uri);
            $response = $this->getClientWithHTMLResponse($client);
            if ($response->code == Status::OK) {
                return (string) $response->body;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Name
     * 
     * @param string $user The user
     * @return string Return the name of a valid user.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws DatabaseException
     * @throws RepositoryException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getName($user) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_NAME);
            $uri .= '/' . urlencode($user);
            $client = Request::get($uri);
            $response = $this->getClientWithHTMLResponse($client);
            if ($response->code == Status::OK) {
                return (string) $response->body;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Create a new user.
     * 
     * @param string $user
     * @param string $password
     * @param string $email
     * @param string $name
     * @param bool $active
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function createUser($user, $password, $email, $name, $active) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_CREATE_USER);
            $params = [];
            $params['user'] = $user;
            $params['password'] = $password;
            $params['email'] = $email;
            $params['name'] = $name;
            $params['active'] = $active;
            $client = Request::post($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Delete a user.
     * 
     * @param string $user
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function deleteUser($user) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_DELETE_USER);
            $uri .= '?user=' . urlencode($user);
            $client = Request::delete($uri);
            $response = $this->getClient($client);
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Update a user.
     * 
     * @param string $user
     * @param string $password
     * @param string $email
     * @param string $name
     * @param bool $active
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function updateUser($user, $password, $email, $name, $active) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_UPDATE_USER);
            $params = [];
            $params['user'] = $user;
            $params['password'] = $password;
            $params['email'] = $email;
            $params['name'] = $name;
            $params['active'] = $active;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Create a new role.
     * 
     * @param string $role
     * @param bool $active
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function createRole($role, $active) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_CREATE_ROLE);
            $params = [];
            $params['role'] = $role;
            $params['active'] = $active;
            $client = Request::post($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Delete a role.
     * 
     * @param string $role
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function deleteRole($role) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_DELETE_ROLE);
            $uri .= '?role=' . urlencode($role);
            $client = Request::delete($uri);
            $response = $this->getClient($client);
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Update a role.
     * 
     * @param string $role
     * @param bool $active
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function updateRole($role, $active) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_UPDATE_ROLE);
            $params = [];
            $params['role'] = $role;
            $params['active'] = $active;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Assign role to a user.
     * 
     * @param string $user
     * @param string $role
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function assignRole($user, $role) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_ASSIGN_ROLE);
            $params = [];
            $params['user'] = $user;
            $params['role'] = $role;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Remove a role from a user.
     * 
     * @param string $user
     * @param string $role
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws WebServiceException
     * @throws UnknowException
     */
    public function removeRole($user, $role) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_REMOVE_ROLE);
            $params = [];
            $params['user'] = $user;
            $params['role'] = $role;
            $client = Request::put($uri);
            $client->body($params, Mime::FORM);
            $client->authenticateWith($this->user, $this->password);
            $response = $client->send();
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else if ($error == TypeException::WEB_SERVICE_EXCEPTION) {
                            throw new WebServiceException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Change the security of a node.
     * 
     * @param ChangeSecurity $changeSecurity
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PathNotFoundException
     * @throws RepositoryException
     * @throws DatabaseException
     * @throws UnknowException
     */
    public function changeSecurity(ChangeSecurity $changeSecurity) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_CHANGE_SECURITY);
            $client = Request::put($uri);
            $changeSecurityXML = new \SimpleXMLElement('<changeSecurity></changeSecurity>');
            $changeSecurityXML->addChild('nodeId', $changeSecurity->getNodeId());
            if ($changeSecurity->isRecursive() == 1) {
                $changeSecurityXML->addChild('recursive', 'true');
            } else {
                $changeSecurityXML->addChild('recursive', 'false');
            }
            $grantedRolesXML = $changeSecurityXML->addChild('grantedRolesList');
            foreach ($changeSecurity->getGrantedRoles() as $grantedRole) {
                $grantedRoleXML = $grantedRolesXML->addChild('grantedRole');
                $grantedRoleXML->addChild('role', $grantedRole->getRole());
                $grantedRoleXML->addChild('permissions', $grantedRole->getPermissions());
            }

            $grantedUsersXML = $changeSecurityXML->addChild('grantedUsersList');
            foreach ($changeSecurity->getGrantedUsers() as $grantedUser) {
                $grantedUserXML = $grantedUsersXML->addChild('grantedUser');
                $grantedUserXML->addChild('user', $grantedUser->getUser());
                $grantedUserXML->addChild('permissions', $grantedUser->getPermissions());
            }

            $revokedRolesXML = $changeSecurityXML->addChild('revokedRolesList');
            foreach ($changeSecurity->getRevokedRoles() as $revokedRole) {
                $revokedRoleXML = $revokedRolesXML->addChild('revokedRole');
                $revokedRoleXML->addChild('role', $revokedRole->getRole());
                $revokedRoleXML->addChild('permissions', $revokedRole->getPermissions());
            }

            $revokedUsersXML = $changeSecurityXML->addChild('revokedUsersList');
            foreach ($changeSecurity->getRevokeUsers() as $revokedUser) {
                $revokedUserXML = $revokedUsersXML->addChild('revokedUser');
                $revokedUserXML->addChild('user', $revokedUser->getUser());
                $revokedUserXML->addChild('permissions', $revokedUser->getPermissions());
            }

            $client->body($changeSecurityXML->asXML());
            $response = $this->getClient($client);
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PATH_NOT_FOUND_EXCEPTION) {
                            throw new PathNotFoundException($error . ': ' . $msg);
                        } else if ($error == TypeException::REPOSITORY_EXCEPTION) {
                            throw new RepositoryException($error . ': ' . $msg);
                        } else if ($error == TypeException::DATABASE_EXCEPTION) {
                            throw new DatabaseException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get Profiles
     * 
     * Each user has assigned one profile that enables more or less OpenKM UI features.
     * 
     * @param bool $filterByAction The parameter filterByActive when enabled the method will return only the active profiles, otherwise will return all avaliable profiles.
     * @return array(ProfileSimple) Return the list of all profiles.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getProfiles($filterByAction) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_PROFILES);
            $uri .= '/' . ($filterByAction == 1 ? 'true' : 'false');
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $profiles = [];
                foreach ($response->body->profile as $profileXML) {
                    $profileSimple = new ProfileSimple();
                    $profileSimple->setId((string) $profileXML->id);
                    $profileSimple->setName((string) $profileXML->name);
                    $profiles[] = $profileSimple;
                }
                return $profiles;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Get User Profile
     * 
     * Each user has assigned one profile that enables more or less OpenKM UI features.
     * 
     * @param string $userId The user
     * @return ProfileSimple Return the profile assigned to a user.
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function getUserProfile($userId) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_GET_USER_PROFILE);
            $uri .= '/' . urlencode($userId);
            $client = Request::get($uri);
            $response = $this->getClient($client);
            if ($response->code == Status::OK) {
                $profileSimple = new ProfileSimple();
                $profileSimple->setId((string) $response->body->id);
                $profileSimple->setName((string) $response->body->name);
                return $profileSimple;
            } else {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

    /**
     * Change the assigned profile to a user
     * 
     * Each user has assigned one profile that enables more or less OpenKM UI features.
     * 
     * @param string $userId The id user
     * @param int $profileId The id profile
     * @throws ConnectionErrorException
     * @throws AccessDeniedException
     * @throws PrincipalAdapterException
     * @throws UnknowException
     */
    public function setUserProfile($userId, $profileId) {
        try {
            $uri = UriHelper::getUri($this->host, UriHelper::AUTH_SET_USER_PROFILE);
            $uri .= '/' . urlencode($userId) . '/' . urlencode($profileId);
            $client = Request::put($uri);
            $response = $this->getClient($client);
            if ($response->code != Status::NO_CONTENT) {
                if ($response->code == Status::UNAUTHORIZED) {
                    throw new AccessDeniedException($response->body, $response->code);
                } else if ($response->code == Status::INTERNAL_SERVER_ERROR) {
                    $position = strpos($response->body, ':');
                    if ($position) {
                        $error = substr($response->body, 0, $position);
                        $msg = substr($response->body, $position + 1, strlen($response->body));
                        if ($error == TypeException::PRINCIPAL_ADAPTER_EXCEPTION) {
                            throw new PrincipalAdapterException($error . ': ' . $msg);
                        } else {
                            throw new UnknowException($error . ': ' . $msg);
                        }
                    } else {
                        throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                    }
                } else {
                    throw new UnknowException("HTTP error code " . $response->code . ": " . $response->body);
                }
            }
        } catch (ConnectionErrorException $cee) {
            throw new ConnectionErrorException('ConnectionErrorException: ' . $cee->getMessage());
        }
    }

}

?>
