Esempio n. 1
0
    def create(self, username, **kwargs):
        """
        Create a user in Keycloak

        http://www.keycloak.org/docs-api/3.4/rest-api/index.html#_users_resource

        :param str username:
        :param object credentials: (optional)
        :param str first_name: (optional)
        :param str last_name: (optional)
        :param str email: (optional)
        :param boolean enabled: (optional)
        """
        payload = OrderedDict(username=username)

        for key in USER_KWARGS:
            from keycloak.admin.clientroles import to_camel_case
            if key in kwargs:
                payload[to_camel_case(key)] = kwargs[key]

        return self._client.post(
            url=self._client.get_full_url(
                self.get_path('collection', realm=self._realm_name)
            ),
            data=json.dumps(payload, sort_keys=True)
        )
Esempio n. 2
0
    def update(self, **kwargs):
        """
        Update existing user.

        https://www.keycloak.org/docs-api/2.5/rest-api/index.html#_userrepresentation

        :param str first_name: first_name for user
        :param str last_name: last_name for user
        :param str email: Email for user
        :param bool email_verified: User email verified
        :param Map attributes: Atributes in user
        :param string array realm_roles: Realm Roles
        :param Map client_roles: Client Roles
        :param string array groups: Groups for user
        """
        payload = {}
        for k, v in self.user.items():
            payload[k] = v
        for key in USER_KWARGS:
            from keycloak.admin.clientroles import to_camel_case
            if key in kwargs:
                payload[to_camel_case(key)] = kwargs[key]
        result = self._client.put(
            url=self._client.get_full_url(
                self.get_path(
                    'single', realm=self._realm_name, user_id=self._user_id
                )
            ),
            data=json.dumps(payload, sort_keys=True)
        )
        self.get()
        return result
Esempio n. 3
0
    def create(self, name, **kwargs):
        """
        Create a group in Keycloak

        https://www.keycloak.org/docs-api/7.0/rest-api/index.html#_grouprepresentation

        :param name
        :param path
        :param access
        :param attributes
        :param client_roles
        :param realm_roles
        :param sub_groups
        """
        payload = OrderedDict(name=name)
        for key in GROUPS_KWARGS:
            from keycloak.admin.clientroles import to_camel_case
            if key in kwargs:
                payload[to_camel_case(key)] = kwargs[key]

        return self._client.post(url=self._client.get_full_url(
            self.get_path('collection', realm=self._realm_name)),
                                 data=json.dumps(payload))
Esempio n. 4
0
def get_or_create_user(federated_user_id=None,
                       federated_user_name=None,
                       federated_provider=None,
                       check_federated_user=None,
                       email=None,
                       required_actions=None,
                       **kwargs) -> keycloak.admin.users.User:
    if federated_user_id or check_federated_user or email:
        user = get_user_by_federated_identity(federated_user_id,
                                              federated_user_name,
                                              federated_provider,
                                              check_federated_user, email)
        if user:
            return user

    admin_client = clients.get_keycloak_admin_client()

    users = []
    first = 0
    inc = 500
    while True:
        new_users = admin_client._client.get(
            url=admin_client._client.get_full_url(
                'auth/admin/realms/{realm}/users?first={first}&max={max}'.
                format(realm=admin_client._name, first=first, max=inc)))
        users.extend(new_users)
        if len(new_users) < inc:
            break
        first += inc

    # If neither worked; create a new user
    def username_exists(username):
        return next(filter(lambda u: u.get("username") == username, users),
                    None) is not None

    def gen_username(num=3):
        return "-".join(list(map(lambda _: random.choice(WORDS), range(num))))

    def gen_username_from_name():
        first_name = kwargs.get("first_name", "").strip().lower().replace(
            " ", "-").replace("\t", "-")
        last_name = kwargs.get("last_name", "").strip().lower().replace(
            " ", "-").replace("\t", "-")
        if first_name and last_name:
            return f"{first_name}-{last_name}"
        elif first_name:
            return first_name
        elif last_name:
            return last_name

    preferred_username = email if email else (gen_username_from_name() if (
        kwargs.get("first_name") or kwargs.get("last_name")) else
                                              gen_username())
    while username_exists(preferred_username):
        preferred_username = gen_username()

    attributes = {}
    fields = {}
    for k, v in kwargs.items():
        if k in BASIC_FIELDS:
            fields[k] = v
        else:
            attributes[k] = v

    if email:
        fields["email"] = email

    payload = {
        "username":
        preferred_username,
        "enabled":
        True,
        "federatedIdentities": [{
            "identityProvider": federated_provider,
            "userId": federated_user_id,
            "userName": federated_user_name,
        }] if federated_provider and federated_user_id and federated_user_name
        else [],
        "attributes":
        attributes,
        "requiredActions":
        required_actions
    }
    for key in fields:
        payload[to_camel_case(key)] = fields[key]
    r = admin_client.users._client._realm.client.session.post(
        url=admin_client.users._client.get_full_url(
            "/auth/admin/realms/{realm}/users".format(
                realm=admin_client.users._realm_name)),
        data=json.dumps(payload),
        headers=admin_client.users._client._add_auth_header(headers=None))
    r.raise_for_status()
    user = admin_client.users.by_id(r.headers["Location"].split("/")[-1]).user

    if required_actions is not None and email:
        user_required_actions(user.get("id"), required_actions)
    return user