github.com/yaegashi/msgraph.go@v0.1.4/cmd/msgraph-spoget/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "flag" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "log" 10 "net/http" 11 "os" 12 13 "github.com/yaegashi/msgraph.go/jsonx" 14 "github.com/yaegashi/msgraph.go/msauth" 15 msgraph "github.com/yaegashi/msgraph.go/v1.0" 16 "golang.org/x/oauth2" 17 ) 18 19 const ( 20 defaultTenantID = "common" 21 defaultClientID = "45c7f99c-0a94-42ff-a6d8-a8d657229e8c" 22 ) 23 24 var defaultScopes = []string{"Sites.Read.All", "Files.Read.All"} 25 26 // Config is serializable configuration 27 type Config struct { 28 TenantID string `json:"tenant_id,omitempty"` 29 ClientID string `json:"client_id,omitempty"` 30 ClientSecret string `json:"client_secret,omitempty"` 31 TokenCache string `json:"token_cache,omitempty"` 32 } 33 34 // App is application 35 type App struct { 36 Config 37 URL string 38 TokenSource oauth2.TokenSource 39 GraphClient *msgraph.GraphServiceRequestBuilder 40 } 41 42 // Authenticate performs OAuth2 authentication 43 func (app *App) Authenticate(ctx context.Context) error { 44 var err error 45 m := msauth.NewManager() 46 if app.ClientSecret == "" { 47 if app.TokenCache != "" { 48 // ignore errors 49 m.LoadFile(app.TokenCache) 50 } 51 app.TokenSource, err = m.DeviceAuthorizationGrant(ctx, app.TenantID, app.ClientID, defaultScopes, nil) 52 if err != nil { 53 return err 54 } 55 if app.TokenCache != "" { 56 err = m.SaveFile(app.TokenCache) 57 if err != nil { 58 return err 59 } 60 } 61 } else { 62 scopes := []string{msauth.DefaultMSGraphScope} 63 app.TokenSource, err = m.ClientCredentialsGrant(ctx, app.TenantID, app.ClientID, app.ClientSecret, scopes) 64 if err != nil { 65 return err 66 } 67 } 68 app.GraphClient = msgraph.NewClient(oauth2.NewClient(ctx, app.TokenSource)) 69 return nil 70 } 71 72 // Main is main routine 73 func (app *App) Main(ctx context.Context) error { 74 if app.URL == "" { 75 return fmt.Errorf("URL not specified") 76 } 77 err := app.Authenticate(ctx) 78 if err != nil { 79 return err 80 } 81 itemRB, err := app.GraphClient.GetDriveItemByURL(ctx, app.URL) 82 if err != nil { 83 return err 84 } 85 itemRB.Workbook().Worksheets() 86 app.GraphClient.Workbooks() 87 item, err := itemRB.Request().Get(ctx) 88 if err != nil { 89 return err 90 } 91 log.Printf("Download to %#v (%d bytes)", *item.Name, *item.Size) 92 if url, ok := item.GetAdditionalData("@microsoft.graph.downloadUrl"); ok { 93 res, err := http.Get(url.(string)) 94 if err != nil { 95 return err 96 } 97 defer res.Body.Close() 98 if res.StatusCode != http.StatusOK { 99 b, _ := ioutil.ReadAll(res.Body) 100 return fmt.Errorf("%s: %s", res.Status, string(b)) 101 } 102 f, err := os.Create(*item.Name) 103 if err != nil { 104 return err 105 } 106 defer f.Close() 107 _, err = io.Copy(f, res.Body) 108 if err != nil { 109 return err 110 } 111 return nil 112 } 113 return fmt.Errorf("unknown download URL") 114 } 115 116 func main() { 117 config := "" 118 app := &App{} 119 flag.StringVar(&config, "config", "", "Config file path") 120 flag.StringVar(&app.TenantID, "tenant-id", "", "Tenant ID (default:"+defaultTenantID+")") 121 flag.StringVar(&app.ClientID, "client-id", "", "Client ID (default: "+defaultClientID+")") 122 flag.StringVar(&app.ClientSecret, "client-secret", "", "Client secret (for client credentials grant)") 123 flag.StringVar(&app.TokenCache, "token-cache", "", "OAuth2 token cache path") 124 flag.StringVar(&app.URL, "url", "", "URL") 125 flag.Parse() 126 127 cfg := &Config{ 128 TenantID: defaultTenantID, 129 ClientID: defaultClientID, 130 } 131 if config != "" { 132 b, err := ioutil.ReadFile(config) 133 if err != nil { 134 log.Fatal(err) 135 } 136 err = jsonx.Unmarshal(b, cfg) 137 if err != nil { 138 log.Fatal(err) 139 } 140 } 141 if app.TenantID == "" { 142 app.TenantID = cfg.TenantID 143 } 144 if app.ClientID == "" { 145 app.ClientID = cfg.ClientID 146 } 147 if app.ClientSecret == "" { 148 app.ClientSecret = cfg.ClientSecret 149 } 150 if app.TokenCache == "" { 151 app.TokenCache = cfg.TokenCache 152 } 153 154 ctx := context.Background() 155 err := app.Main(ctx) 156 if err != nil { 157 log.Fatal(err) 158 os.Exit(1) 159 } 160 }