forked from TrueCloudLab/rclone
box: allow authentication with access token - fixes #4114
This commit is contained in:
parent
62f0bbb598
commit
8bf265c775
2 changed files with 54 additions and 23 deletions
|
@ -87,13 +87,16 @@ func init() {
|
||||||
Config: func(name string, m configmap.Mapper) {
|
Config: func(name string, m configmap.Mapper) {
|
||||||
jsonFile, ok := m.Get("box_config_file")
|
jsonFile, ok := m.Get("box_config_file")
|
||||||
boxSubType, boxSubTypeOk := m.Get("box_sub_type")
|
boxSubType, boxSubTypeOk := m.Get("box_sub_type")
|
||||||
|
boxAccessToken, boxAccessTokenOk := m.Get("access_token")
|
||||||
var err error
|
var err error
|
||||||
|
// If using box config.json, use JWT auth
|
||||||
if ok && boxSubTypeOk && jsonFile != "" && boxSubType != "" {
|
if ok && boxSubTypeOk && jsonFile != "" && boxSubType != "" {
|
||||||
err = refreshJWTToken(jsonFile, boxSubType, name, m)
|
err = refreshJWTToken(jsonFile, boxSubType, name, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to configure token with jwt authentication: %v", err)
|
log.Fatalf("Failed to configure token with jwt authentication: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
// Else, if not using an access token, use oauth2
|
||||||
|
} else if boxAccessToken == "" || !boxAccessTokenOk {
|
||||||
err = oauthutil.Config("box", name, m, oauthConfig, nil)
|
err = oauthutil.Config("box", name, m, oauthConfig, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to configure token with oauth authentication: %v", err)
|
log.Fatalf("Failed to configure token with oauth authentication: %v", err)
|
||||||
|
@ -114,6 +117,9 @@ func init() {
|
||||||
}, {
|
}, {
|
||||||
Name: "box_config_file",
|
Name: "box_config_file",
|
||||||
Help: "Box App config.json location\nLeave blank normally." + env.ShellExpandHelp,
|
Help: "Box App config.json location\nLeave blank normally." + env.ShellExpandHelp,
|
||||||
|
}, {
|
||||||
|
Name: "access_token",
|
||||||
|
Help: "Box App Primary Access Token\nLeave blank normally.",
|
||||||
}, {
|
}, {
|
||||||
Name: "box_sub_type",
|
Name: "box_sub_type",
|
||||||
Default: "user",
|
Default: "user",
|
||||||
|
@ -247,6 +253,7 @@ type Options struct {
|
||||||
CommitRetries int `config:"commit_retries"`
|
CommitRetries int `config:"commit_retries"`
|
||||||
Enc encoder.MultiEncoder `config:"encoding"`
|
Enc encoder.MultiEncoder `config:"encoding"`
|
||||||
RootFolderID string `config:"root_folder_id"`
|
RootFolderID string `config:"root_folder_id"`
|
||||||
|
AccessToken string `config:"access_token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fs represents a remote box
|
// Fs represents a remote box
|
||||||
|
@ -385,16 +392,22 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
root = parsePath(root)
|
root = parsePath(root)
|
||||||
oAuthClient, ts, err := oauthutil.NewClient(name, m, oauthConfig)
|
|
||||||
|
client := fshttp.NewClient(fs.Config)
|
||||||
|
var ts *oauthutil.TokenSource
|
||||||
|
// If not using an accessToken, create an oauth client and tokensource
|
||||||
|
if opt.AccessToken == "" {
|
||||||
|
client, ts, err = oauthutil.NewClient(name, m, oauthConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to configure Box")
|
return nil, errors.Wrap(err, "failed to configure Box")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f := &Fs{
|
f := &Fs{
|
||||||
name: name,
|
name: name,
|
||||||
root: root,
|
root: root,
|
||||||
opt: *opt,
|
opt: *opt,
|
||||||
srv: rest.NewClient(oAuthClient).SetRoot(rootURL),
|
srv: rest.NewClient(client).SetRoot(rootURL),
|
||||||
pacer: fs.NewPacer(pacer.NewDefault(pacer.MinSleep(minSleep), pacer.MaxSleep(maxSleep), pacer.DecayConstant(decayConstant))),
|
pacer: fs.NewPacer(pacer.NewDefault(pacer.MinSleep(minSleep), pacer.MaxSleep(maxSleep), pacer.DecayConstant(decayConstant))),
|
||||||
uploadToken: pacer.NewTokenDispenser(fs.Config.Transfers),
|
uploadToken: pacer.NewTokenDispenser(fs.Config.Transfers),
|
||||||
}
|
}
|
||||||
|
@ -404,9 +417,15 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
}).Fill(f)
|
}).Fill(f)
|
||||||
f.srv.SetErrorHandler(errorHandler)
|
f.srv.SetErrorHandler(errorHandler)
|
||||||
|
|
||||||
|
// If using an accessToken, set the Authorization header
|
||||||
|
if f.opt.AccessToken != "" {
|
||||||
|
f.srv.SetHeader("Authorization", "Bearer "+f.opt.AccessToken)
|
||||||
|
}
|
||||||
|
|
||||||
jsonFile, ok := m.Get("box_config_file")
|
jsonFile, ok := m.Get("box_config_file")
|
||||||
boxSubType, boxSubTypeOk := m.Get("box_sub_type")
|
boxSubType, boxSubTypeOk := m.Get("box_sub_type")
|
||||||
|
|
||||||
|
if ts != nil {
|
||||||
// If using box config.json and JWT, renewing should just refresh the token and
|
// If using box config.json and JWT, renewing should just refresh the token and
|
||||||
// should do so whether there are uploads pending or not.
|
// should do so whether there are uploads pending or not.
|
||||||
if ok && boxSubTypeOk && jsonFile != "" && boxSubType != "" {
|
if ok && boxSubTypeOk && jsonFile != "" && boxSubType != "" {
|
||||||
|
@ -422,6 +441,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get rootFolderID
|
// Get rootFolderID
|
||||||
rootID := f.opt.RootFolderID
|
rootID := f.opt.RootFolderID
|
||||||
|
@ -1258,8 +1278,10 @@ func (o *Object) upload(ctx context.Context, in io.Reader, leaf, directoryID str
|
||||||
//
|
//
|
||||||
// The new object may have been created if an error is returned
|
// The new object may have been created if an error is returned
|
||||||
func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (err error) {
|
func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (err error) {
|
||||||
|
if o.fs.tokenRenewer != nil {
|
||||||
o.fs.tokenRenewer.Start()
|
o.fs.tokenRenewer.Start()
|
||||||
defer o.fs.tokenRenewer.Stop()
|
defer o.fs.tokenRenewer.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
size := src.Size()
|
size := src.Size()
|
||||||
modTime := src.ModTime(ctx)
|
modTime := src.ModTime(ctx)
|
||||||
|
|
|
@ -41,9 +41,18 @@ client_secret>
|
||||||
Box App config.json location
|
Box App config.json location
|
||||||
Leave blank normally.
|
Leave blank normally.
|
||||||
Enter a string value. Press Enter for the default ("").
|
Enter a string value. Press Enter for the default ("").
|
||||||
config_json>
|
box_config_file>
|
||||||
'enterprise' or 'user' depending on the type of token being requested.
|
Box App Primary Access Token
|
||||||
|
Leave blank normally.
|
||||||
|
Enter a string value. Press Enter for the default ("").
|
||||||
|
access_token>
|
||||||
|
|
||||||
Enter a string value. Press Enter for the default ("user").
|
Enter a string value. Press Enter for the default ("user").
|
||||||
|
Choose a number from below, or type in your own value
|
||||||
|
1 / Rclone should act on behalf of a user
|
||||||
|
\ "user"
|
||||||
|
2 / Rclone should act on behalf of a service account
|
||||||
|
\ "enterprise"
|
||||||
box_sub_type>
|
box_sub_type>
|
||||||
Remote config
|
Remote config
|
||||||
Use auto config?
|
Use auto config?
|
||||||
|
|
Loading…
Reference in a new issue