go-ayo/common을 gocommon으로 분리
This commit is contained in:
356
azure/graph.go
Normal file
356
azure/graph.go
Normal file
@ -0,0 +1,356 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Graph struct {
|
||||
*accessToken
|
||||
tenantId string
|
||||
groupId string
|
||||
}
|
||||
|
||||
func NewGraphByEnv() *Graph {
|
||||
tenantId := os.Getenv("GRAPH_TENANT_ID")
|
||||
groupId := os.Getenv("GRAPH_GROUP_ID")
|
||||
return NewGraph(tenantId, groupId)
|
||||
}
|
||||
|
||||
func NewGraph(tenantId string, groupId string) *Graph {
|
||||
return &Graph{
|
||||
accessToken: &accessToken{
|
||||
url: fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenantId),
|
||||
values: url.Values{
|
||||
"grant_type": {"client_credentials"},
|
||||
"client_id": {microsoftAppId()},
|
||||
"scope": {"https://graph.microsoft.com/.default"},
|
||||
"client_secret": {microsoftAppPassword()},
|
||||
},
|
||||
},
|
||||
tenantId: tenantId,
|
||||
groupId: groupId,
|
||||
}
|
||||
}
|
||||
|
||||
func (s Graph) GroupId() string {
|
||||
return s.groupId
|
||||
}
|
||||
|
||||
var errGroupIdMissing = errors.New("GRAPH_GROUP_ID is missing")
|
||||
|
||||
func (s Graph) ReadFile(relativePath string) (io.ReadCloser, error) {
|
||||
if len(s.groupId) == 0 {
|
||||
return nil, errGroupIdMissing
|
||||
}
|
||||
|
||||
token, err := s.getAuthoizationToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/groups/%s/drive/root:/%s:/content", s.groupId, relativePath)
|
||||
req, _ := http.NewRequest("GET", requrl, nil)
|
||||
|
||||
req.Header.Add("Authorization", token)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
resp.Body.Close()
|
||||
return nil, errors.New(resp.Status)
|
||||
}
|
||||
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
func (s Graph) GetWebURLOfFile(relativePath string) (string, error) {
|
||||
if len(s.groupId) == 0 {
|
||||
return "", errGroupIdMissing
|
||||
}
|
||||
|
||||
token, err := s.getAuthoizationToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
requrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/groups/%s/drive/root:/%s:", s.groupId, relativePath)
|
||||
req, _ := http.NewRequest("GET", requrl, nil)
|
||||
|
||||
req.Header.Add("Authorization", token)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
itemdoc, _ := io.ReadAll(resp.Body)
|
||||
var item map[string]interface{}
|
||||
json.Unmarshal(itemdoc, &item)
|
||||
|
||||
url, ok := item["webUrl"]
|
||||
if ok {
|
||||
return url.(string), nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (s Graph) DownloadFile(relativePath string, outputFile string) error {
|
||||
body, err := s.ReadFile(relativePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer body.Close()
|
||||
|
||||
// Create the file
|
||||
out, err := os.Create(outputFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, body)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s Graph) UploadStream(relativePath string, reader io.Reader) (string, error) {
|
||||
if len(s.groupId) == 0 {
|
||||
return "", errGroupIdMissing
|
||||
}
|
||||
|
||||
token, err := s.getAuthoizationToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
requrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/groups/%s/drive/root:/%s:/content", s.groupId, relativePath)
|
||||
req, _ := http.NewRequest("PUT", requrl, reader)
|
||||
|
||||
req.Header.Add("Authorization", token)
|
||||
req.Header.Add("Content-Type", "text/plain")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
unquot, _ := unescapeUnicodeCharactersInJSON(body)
|
||||
|
||||
var drive map[string]interface{}
|
||||
err = json.Unmarshal([]byte(unquot), &drive)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if errnode, ok := drive["error"]; ok {
|
||||
errmsg := errnode.(map[string]interface{})["message"].(string)
|
||||
return "", errors.New(errmsg)
|
||||
}
|
||||
|
||||
return drive["webUrl"].(string), nil
|
||||
}
|
||||
|
||||
func (s Graph) UploadBytes(relativePath string, content []byte) (string, error) {
|
||||
return s.UploadStream(relativePath, bytes.NewReader(content))
|
||||
}
|
||||
|
||||
func (s Graph) GetChannelFilesFolderName(channel string) (string, error) {
|
||||
if len(s.groupId) == 0 {
|
||||
return "", errGroupIdMissing
|
||||
}
|
||||
|
||||
token, err := s.getAuthoizationToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
requrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/teams/%s/channels/%s/filesFolder", s.groupId, channel)
|
||||
req, _ := http.NewRequest("GET", requrl, nil)
|
||||
req.Header.Add("Authorization", token)
|
||||
req.Header.Add("Accept", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
unquot, _ := unescapeUnicodeCharactersInJSON(body)
|
||||
|
||||
var drive map[string]interface{}
|
||||
err = json.Unmarshal([]byte(unquot), &drive)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if errnode, ok := drive["error"]; ok {
|
||||
errmsg := errnode.(map[string]interface{})["message"].(string)
|
||||
return "", errors.New(errmsg)
|
||||
}
|
||||
|
||||
return drive["name"].(string), nil
|
||||
}
|
||||
|
||||
func (s Graph) listChildren(path string) (map[string]interface{}, error) {
|
||||
if len(s.groupId) == 0 {
|
||||
return nil, errGroupIdMissing
|
||||
}
|
||||
|
||||
token, err := s.getAuthoizationToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// groupId := "612620b7-cd90-4b3f-a9bd-d34cddf52517"
|
||||
var requrl string
|
||||
if len(path) == 0 {
|
||||
requrl = fmt.Sprintf("https://graph.microsoft.com/v1.0/groups/%s/drive/root/children", s.groupId)
|
||||
} else {
|
||||
requrl = fmt.Sprintf("https://graph.microsoft.com/v1.0/groups/%s/drive/root:/%s:/children", s.groupId, path)
|
||||
}
|
||||
req, _ := http.NewRequest("GET", requrl, nil)
|
||||
req.Header.Add("Authorization", token)
|
||||
req.Header.Add("Accept", "application/json")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
unquot, _ := unescapeUnicodeCharactersInJSON(body)
|
||||
|
||||
var drive map[string]interface{}
|
||||
err = json.Unmarshal([]byte(unquot), &drive)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if errnode, ok := drive["error"]; ok {
|
||||
errmsg := errnode.(map[string]interface{})["message"].(string)
|
||||
return nil, errors.New(errmsg)
|
||||
}
|
||||
|
||||
return drive, nil
|
||||
}
|
||||
|
||||
func (s Graph) ListFolders(parent string) ([]string, error) {
|
||||
drive, err := s.listChildren(parent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var output []string
|
||||
items := drive["value"].([]interface{})
|
||||
for _, item := range items {
|
||||
itemobj := item.(map[string]interface{})
|
||||
if _, ok := itemobj["file"]; !ok {
|
||||
output = append(output, itemobj["name"].(string))
|
||||
}
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
type FileMeta struct {
|
||||
Path string `json:"path"`
|
||||
LastModified time.Time `json:"lastModified"`
|
||||
}
|
||||
|
||||
func (s Graph) ListFiles(parent string) ([]FileMeta, error) {
|
||||
drive, err := s.listChildren(parent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var output []FileMeta
|
||||
items := drive["value"].([]interface{})
|
||||
for _, item := range items {
|
||||
itemobj := item.(map[string]interface{})
|
||||
if _, ok := itemobj["file"]; ok {
|
||||
modTime, _ := time.Parse(time.RFC3339, itemobj["lastModifiedDateTime"].(string))
|
||||
|
||||
output = append(output, FileMeta{
|
||||
Path: path.Join(parent, itemobj["name"].(string)),
|
||||
LastModified: modTime,
|
||||
})
|
||||
}
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s Graph) GetChannels() (map[string]string, error) {
|
||||
if len(s.groupId) == 0 {
|
||||
return nil, errGroupIdMissing
|
||||
}
|
||||
|
||||
token, err := s.getAuthoizationToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/teams/%s/channels", s.groupId)
|
||||
req, _ := http.NewRequest("GET", requrl, nil)
|
||||
req.Header.Add("Authorization", token)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var raw map[string]interface{}
|
||||
if err = json.Unmarshal(body, &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if errnode, ok := raw["error"]; ok {
|
||||
return nil, errors.New(errnode.(map[string]interface{})["message"].(string))
|
||||
}
|
||||
|
||||
if r, ok := raw["value"]; ok {
|
||||
valuenode := r.([]interface{})
|
||||
output := make(map[string]string)
|
||||
for _, v := range valuenode {
|
||||
data := v.(map[string]interface{})
|
||||
id := data["id"].(string)
|
||||
displayname := data["displayName"].(string)
|
||||
output[id] = displayname
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("error")
|
||||
}
|
||||
Reference in New Issue
Block a user