# 사용자 및 역할 관리

## 개요

Panther API는 다음 사용자 및 역할 작업을 지원합니다:

* 사용자 목록
* ID 또는 이메일 주소로 사용자 가져오기
* 새 사용자 초대
* 사용자의 정보 및 역할 업데이트
* 사용자 삭제
* 역할 목록
* ID 또는 이름으로 역할 가져오기
* 새 역할 생성
* 역할의 정보 및 권한 업데이트
* 역할 삭제

콘솔의 API 플레이그라운드 또는 GraphQL-over-HTTP API를 사용하여 Panther의 API를 호출할 수 있습니다. 이러한 방법에 대한 자세한 내용은 [Panther API](https://docs.panther.com/ko/panther/api/..#step-1-choose-a-method-for-invoking-the-api).

아래 섹션에서 핵심 사용자 및 역할 관리 작업에 대한 GraphQL 쿼리, 뮤테이션 및 엔드투엔드 워크플로 예제를 확인하세요.

## 일반적인 사용자 및 역할 관리 작업

아래는 Panther에서 가장 일반적인 GraphQL 사용자 및 역할 관리 작업의 일부입니다. 이 예제들은 GraphQL 클라이언트(또는)로 전송해야 하는 문서를 보여줍니다. `curl`)을 사용하여 Panther의 GraphQL API를 호출하기 위해 전송해야 하는 문서를 보여줍니다.

참고:  `createdAt` 필드는 ISO 8601 날짜 및 시간 표준입니다.

#### 사용자 목록 조회

```graphql
query users {
  users {
    id
    givenName
    familyName
    email
    status
    createdAt
    lastLoggedInAt
    role {
      이름
      id
      권한
    }
  }
}
```

#### 사용자 조회

{% tabs %}
{% tab title="이메일 주소로 사용자 조회" %}

```graphql
query user {
  userByEmail(email: "example@domain.com") {
    id
    givenName
    familyName
    email
    role {
      이름
      id
      권한
    }
    status
    createdAt
  }
}
```

{% endtab %}

{% tab title="ID로 사용자 조회" %}

```graphql
query user {
  userById(id: "8h81hfh-ij828db") {
    id
    givenName
    familyName
    email
    role {
      이름
      id
      권한
    }
    status
    createdAt
  }
}
```

{% endtab %}
{% endtabs %}

#### 새 사용자 초대

```graphql
mutation inviteUser {
    inviteUser(input: {
        email: "example@domain.com"
        givenName: "firstname"
        familyName: "lastname"
        role: {
            kind: NAME
            value: "Analyst"
        }
    })
    {
        user {
            id
            status
        }
    }
  }
```

#### 사용자 업데이트

```graphql
mutation updateUser {
    updateUser(input: {
        id: "8h81hfh-ij828db"
        familyName: "newName"
    })
    {
        user {
            email
            givenName
            familyName
        }
    }
}
```

#### 사용자 삭제

```graphql
mutation deleteUser{
  deleteUser(input: {
    id: "8h81hfh-ij828db"
  })
  {
    id # 삭제 작업은 `user` 객체를 반환하지 않습니다; ID만 반환됩니다
  }
}
```

#### 역할 목록 조회

```graphql
query roles {
  roles( 
    # 이 입력은 선택 사항입니다. 입력이 없으면 쿼리는 모든 역할을 반환합니다.
    input: {
      nameContains: "admin",
      sortDir: ascending
    }) 
  {
    createdAt
    id
    이름
    권한
    updatedAt
    updatedBy {
      ... on User {
        email
        id
      }
      ... on APIToken {
        id
        이름
      }
    }
    # RBAC 로그 유형별 설정이 활성화된 경우에만 사용됩니다
    logTypeAccess 
    logTypeAccessKind
  }
}
```

#### 역할 조회

{% tabs %}
{% tab title="이름으로 역할 조회" %}

```graphql
query adminRole {
  roleByName(
   name: "admin"
   ) {
    createdAt
    id
    이름
    권한
    updatedAt
    updatedBy {
      ... on User {
        email
        id
      }
      ... on APIToken {
        id
        이름
      }
    }
    # RBAC 로그 유형별 설정이 활성화된 경우에만 사용됩니다
    logTypeAccess 
    logTypeAccessKind
  }
}
```

{% endtab %}

{% tab title="ID로 역할 조회" %}

```graphql
query adminRole {
  roleById(
   id: "feeafade-c545"
   ) {
    createdAt
    id
    logTypeAccess
    logTypeAccessKind
    이름
    권한
    updatedAt
    updatedBy {
      ... on User {
        email
        id
      }
      ... on APIToken {
        id
        이름
      }
    }
    # RBAC 로그 유형별 설정이 활성화된 경우에만 사용됩니다
    logTypeAccess 
    logTypeAccessKind
  }
}
```

{% endtab %}
{% endtabs %}

#### 새 역할 생성

{% hint style="warning" %}
**참고:** 권한 `UserModify` 는 Panther 플랫폼에 대한 전체 관리자 액세스를 제공합니다. 새 역할에 이 권한을 부여할 때 신중하게 결정하세요.
{% endhint %}

{% tabs %}
{% tab title="Basic" %}

```graphql
mutation createRole {
  createRole(input: {
    name: "new-role"
    permissions: [
      UserRead
      AlertRead
    ]
  })
  {  
    role {
      이름
      id
      권한
    }
  }
}
```

{% endtab %}

{% tab title="로그 유형별 RBAC 활성화됨" %}

```graphql
mutation createRole {
  createRole(input: {
    name: "new-role"
    permissions: [
      UserRead
      AlertRead
    ]
    # RBAC 로그 유형별 기능이 활성화된 경우에만 사용됩니다
    logTypeAccess:["AWS.ALB"]
    logTypeAccessKind: ALLOW
  })
  {  
    role {
      이름
      id
      권한
      logTypeAccess
      logTypeAccessKind
    }
  }
}
```

{% endtab %}
{% endtabs %}

#### 역할 업데이트

{% hint style="warning" %}
**참고:** updateRole 입력의 권한에는 **모든** 역할에 대한 원하는 권한이 포함되어야 합니다.
{% endhint %}

{% tabs %}
{% tab title="Basic" %}

```graphql
mutation updateRole {
  updateRole(input: {
    id: "fea8sje-92jdnhc"
    name: "updated-role-name"
    permissions: [
      UserRead
      AlertRead
      AlertModify
    ]
  })
  {
    role {
      이름
      id
      권한
    }
  }
}
```

{% endtab %}

{% tab title="로그 유형별 RBAC 활성화됨" %}

```graphql
mutation updateRole {
  updateRole(input: {
    id: "fea8sje-92jdnhc"
    name: "updated-role-name"
    permissions: [
      UserRead
      AlertRead
      AlertModify
    ]
    # RBAC 로그 유형별 기능이 활성화된 경우에만 사용됩니다
    logTypeAccess:["AWS.ALB"]
    logTypeAccessKind: DENY
  })
  {
    role {
      이름
      id
      권한
      logTypeAccess 
      logTypeAccessKind
    }
  }
}
```

{% endtab %}
{% endtabs %}

#### 역할 삭제

```graphql
mutation deleteRole {
  deleteRole(input: {
    id: "e146c8d8-c6a5"
  })
    {
      id # 삭제 작업은 `role` 객체를 반환하지 않습니다. ID만 반환됩니다.
    }
}
```

## 종단 간 예제

아래에서는 [일반 작업](#common-operations) 예제를 바탕으로 엔드투엔드 흐름을 소개합니다.

#### **새 사용자 관리자 역할을 만들고 해당 역할에 사용자를 초대합니다.**

{% tabs %}
{% tab title="Python" %}

```python
# pip install gql aiohttp

from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport

transport = AIOHTTPTransport(
  url="YOUR_PANTHER_API_URL",
  headers={"X-API-Key": "YOUR_API_KEY"},
)

client = Client(transport=transport, fetch_schema_from_transport=True)

create_user_admin = gql(
  """
  mutation newAdminRole {
    createRole (input: {
      name: "user-admin"
      permissions: [
        UserRead
        UserModify
        OrganizationAPITokenRead
        GeneralSettingsRead
      ]
    }) 
    {
      role {
        이름
        id
      }
    }
  }
  """
)

invite_user = gql(
  """
  mutation inviteUser($input: InviteUserInput!) {
    inviteUser (input: $input) {
      user {
        id
        email
      }
    }
  }
  """
)

new_role_data = client.execute(
  create_user_admin
)

print(f'new role ID is {new_role_data["createRole"]["role"]["id"]}')

response_data = client.execute(
  invite_user,
  variable_values= {
    "input": {
      "email": "newAdmin@domain.local",
      "givenName": "user",
      "familyName": "admin",
      "role": {
        "kind": "ID",
        "value": new_role_data["createRole"]["role"]["id"],
      }
    }
  }
)

print(f'Successfully invited user {response_data["inviteUser"]["user"]["email"]} with role {new_role_data["createRole"]["role"]["name"]}.')
```

{% endtab %}

{% tab title="NodeJS" %}

```javascript
import { GraphQLClient, gql } from "graphql-request";

const client = new GraphQLClient(
  "YOUR_PANTHER_API_URL",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);

// `createUserAdmin` 는 쿼리의 별칭입니다. 완전히 생략할 수 있습니다.
const createUserAdmin = gql`
  mutation newAdminRole {
    createRole(
      input: {
        name: "user-admin"
        permissions: [
          UserRead
          UserModify
          OrganizationAPITokenRead
          GeneralSettingsRead
        ]
      }
    ) {
      role {
        이름
        id
      }
    }
  }
`;

// `inviteUser` 는 뮤테이션의 별칭입니다. 완전히 생략할 수 있습니다.
const inviteUser = gql`
  mutation inviteUser($input: InviteUserInput!) {
    inviteUser(input: $input) {
      user {
        id
        email
      }
    }
  }
`;

(async () => {
  try {
    const newRoleData = await client.request(createUserAdmin);

    const inviteUserOutput = await client.request(inviteUser, {
      input: {
        email: "newAdmin@domain.local",
        givenName: "user",
        familyName: "admin",
        role: {
          kind: "ID",
          value: newRoleData.createRole.role.id
        }
      }
    });

    console.log(
      `Successfully invited user ${inviteUserOutput.inviteUser.user.email} with role ${newRoleData.createRole.role.name}.`
    );
  } catch (err) {
    console.error(err);
  }
})();

```

{% endtab %}
{% endtabs %}
