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  }