123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package azure
- import (
- "encoding/json"
- "errors"
- "fmt"
- "github.com/gravitl/netmaker/logic"
- "github.com/gravitl/netmaker/pro/idp"
- "net/http"
- "net/url"
- )
- type Client struct {
- clientID string
- clientSecret string
- tenantID string
- }
- func NewAzureEntraIDClient() *Client {
- settings := logic.GetServerSettings()
- return &Client{
- clientID: settings.ClientID,
- clientSecret: settings.ClientSecret,
- tenantID: settings.AzureTenant,
- }
- }
- func (a *Client) GetUsers() ([]idp.User, error) {
- accessToken, err := a.getAccessToken()
- if err != nil {
- return nil, err
- }
- client := &http.Client{}
- req, err := http.NewRequest("GET", "https://graph.microsoft.com/v1.0/users?$select=id,userPrincipalName,displayName,accountEnabled", nil)
- if err != nil {
- return nil, err
- }
- req.Header.Add("Authorization", "Bearer "+accessToken)
- req.Header.Add("Accept", "application/json")
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- defer func() {
- _ = resp.Body.Close()
- }()
- var users getUsersResponse
- err = json.NewDecoder(resp.Body).Decode(&users)
- if err != nil {
- return nil, err
- }
- retval := make([]idp.User, len(users.Value))
- for i, user := range users.Value {
- retval[i] = idp.User{
- ID: user.Id,
- Username: user.UserPrincipalName,
- DisplayName: user.DisplayName,
- AccountDisabled: !user.AccountEnabled,
- }
- }
- return retval, nil
- }
- func (a *Client) GetGroups() ([]idp.Group, error) {
- accessToken, err := a.getAccessToken()
- if err != nil {
- return nil, err
- }
- client := &http.Client{}
- req, err := http.NewRequest("GET", "https://graph.microsoft.com/v1.0/groups?$select=id,displayName&$expand=members($select=id)", nil)
- if err != nil {
- return nil, err
- }
- req.Header.Add("Authorization", "Bearer "+accessToken)
- req.Header.Add("Accept", "application/json")
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- defer func() {
- _ = resp.Body.Close()
- }()
- var groups getGroupsResponse
- err = json.NewDecoder(resp.Body).Decode(&groups)
- if err != nil {
- return nil, err
- }
- retval := make([]idp.Group, len(groups.Value))
- for i, group := range groups.Value {
- retvalMembers := make([]string, len(group.Members))
- for j, member := range group.Members {
- retvalMembers[j] = member.Id
- }
- retval[i] = idp.Group{
- ID: group.Id,
- Name: group.DisplayName,
- Members: retvalMembers,
- }
- }
- return retval, nil
- }
- func (a *Client) getAccessToken() (string, error) {
- tokenURL := fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/token", a.tenantID)
- var data = url.Values{}
- data.Set("grant_type", "client_credentials")
- data.Set("client_id", a.clientID)
- data.Set("client_secret", a.clientSecret)
- data.Set("scope", "https://graph.microsoft.com/.default")
- resp, err := http.PostForm(tokenURL, data)
- if err != nil {
- return "", err
- }
- defer func() {
- _ = resp.Body.Close()
- }()
- var tokenResp map[string]interface{}
- err = json.NewDecoder(resp.Body).Decode(&tokenResp)
- if err != nil {
- return "", err
- }
- if token, ok := tokenResp["access_token"].(string); ok {
- return token, nil
- }
- return "", errors.New("failed to get access token")
- }
- type getUsersResponse struct {
- OdataContext string `json:"@odata.context"`
- Value []struct {
- Id string `json:"id"`
- UserPrincipalName string `json:"userPrincipalName"`
- DisplayName string `json:"displayName"`
- AccountEnabled bool `json:"accountEnabled"`
- } `json:"value"`
- }
- type getGroupsResponse struct {
- OdataContext string `json:"@odata.context"`
- Value []struct {
- Id string `json:"id"`
- DisplayName string `json:"displayName"`
- Members []struct {
- OdataType string `json:"@odata.type"`
- Id string `json:"id"`
- } `json:"members"`
- } `json:"value"`
- }
|