Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storage Explorer] _token_refresh_source type change #2710

Merged
merged 20 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
475a05a
[Storage Explorer] _token_refresh_source type change
dphulkar-msft Jun 10, 2024
2508c15
[Storage Explorer] _token_refresh_source type change
dphulkar-msft Jun 10, 2024
5166ed3
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
f6884bb
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
807acaa
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
0a42375
Merge branch 'main' of https://github.com/Azure/azure-storage-azcopy …
dphulkar-msft Jun 10, 2024
089a315
Merge branch 'main' of https://github.com/Azure/azure-storage-azcopy …
dphulkar-msft Jun 10, 2024
753d2cc
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
f6595a0
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
a3baf92
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
4d15d72
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
a1b271f
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
5447bec
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 10, 2024
8ffe903
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 11, 2024
f643dab
Merge branch 'main' of https://github.com/Azure/azure-storage-azcopy …
dphulkar-msft Jun 11, 2024
8d6f217
Merge branch 'main' of https://github.com/Azure/azure-storage-azcopy …
dphulkar-msft Jun 11, 2024
eb27c72
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 11, 2024
56d5d3b
incorporated review comments
dphulkar-msft Jun 12, 2024
c41e36c
incorporated review comments
dphulkar-msft Jun 12, 2024
8d4f7d2
Merge branch 'az-28320197' of https://github.com/Azure/azure-storage-…
dphulkar-msft Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion common/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
package common

import (
"github.com/JeffreyRichter/enum/enum"
"encoding/json"
"reflect"
"runtime"
"strings"

"github.com/JeffreyRichter/enum/enum"
)

type EnvironmentVariable struct {
Expand Down Expand Up @@ -115,6 +117,29 @@ func (d *AutoLoginType) Parse(s string) error {
return err
}

// MarshalJSON customizes the JSON encoding for AutoLoginType
func (d AutoLoginType) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}

// UnmarshalJSON customizes the JSON decoding for AutoLoginType
func (d *AutoLoginType) UnmarshalJSON(data []byte) error {
var v interface{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if strValue, ok := v.(string); ok {
return d.Parse(strValue)
}
// Handle numeric values
if numValue, ok := v.(float64); ok {
*d = AutoLoginType(uint8(numValue))
return nil
}

return nil
}

func ValidAutoLoginTypes() []string {
return []string{
EAutoLoginType.Device().String() + " (Device code workflow)",
Expand Down
5 changes: 2 additions & 3 deletions common/oauthTokenManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func newAzcopyHTTPClient() *http.Client {
Timeout: 10 * time.Second,
KeepAlive: 10 * time.Second,
DualStack: true,
}).Dial, /*Context*/
}).Dial, /*Context*/
MaxIdleConns: 0, // No limit
MaxIdleConnsPerHost: 1000,
IdleConnTimeout: 180 * time.Second,
Expand Down Expand Up @@ -524,15 +524,14 @@ type TokenStoreCredential struct {
// we do not make repeated GetToken calls.
// This is a temporary fix for issue where we would request a
// new token from Stg Exp even while they've not yet populated the
// tokenstore.
// tokenstore.
//
// This is okay because we use same credential on both source and
// destination. If we move to a case where the credentials are
// different, this should be removed.
//
// We should move to a method where the token is always read from
// tokenstore, and azcopy is invoked after tokenstore is populated.
//
var globalTokenStoreCredential *TokenStoreCredential
var globalTsc sync.Once

Expand Down
202 changes: 202 additions & 0 deletions common/oauthTokenManager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// Copyright © 2017 Microsoft <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package common

import (
"context"
"os"
"reflect"
"testing"
)

func TestUserOAuthTokenManager_GetTokenInfo(t *testing.T) {
type args struct {
ctx context.Context
}
tests := []struct {
name string
uotm *UserOAuthTokenManager
args args
setup func(t *testing.T)
want *OAuthTokenInfo
wantErr bool
}{
{
name: "This UT tests if AutoLoginType filled is parsed properly from string to uint8 data type",
uotm: &UserOAuthTokenManager{},
args: args{
ctx: context.Background(),
},
setup: func(t *testing.T) {
tokenInfoJSON := `{
"access_token": "dummy_access_token",
"refresh_token": "dummy_refresh_token",
"expires_in": 0,
"expires_on": 0,
"not_before": 0,
"resource": "dummy_resource",
"token_type": "dummy_token_type",
"_tenant": "dummy_tenant",
"_ad_endpoint": "dummy_ad_endpoint",
"_token_refresh_source": "TokenStore",
"_application_id": "dummy_application_id",
"IdentityInfo": {
"_identity_client_id": "dummy_identity_client_id",
"_identity_object_id": "dummy_identity_object_id",
"_identity_msi_res_id": "dummy_identity_msi_res_id"
},
"SPNInfo": {
"_spn_secret": "dummy_spn_secret",
"_spn_cert_path": "dummy_spn_cert_path"
}
}`

// Set the environment variable AZCOPY_OAUTH_TOKEN_INFO
err := os.Setenv("AZCOPY_OAUTH_TOKEN_INFO", tokenInfoJSON)
if err != nil {
t.Fatalf("Failed to set environment variable: %v", err)
}
},
want: &OAuthTokenInfo{
Tenant: "dummy_tenant",
ActiveDirectoryEndpoint: "dummy_ad_endpoint",
LoginType: 255,
ApplicationID: "dummy_application_id",
IdentityInfo: IdentityInfo{
ClientID: "dummy_identity_client_id",
ObjectID: "dummy_identity_object_id",
MSIResID: "dummy_identity_msi_res_id",
},
SPNInfo: SPNInfo{
Secret: "dummy_spn_secret",
CertPath: "dummy_spn_cert_path",
},
},
wantErr: false,
},
{
name: "This UT tests if AutoLoginType filled is parsed properly to uint8 data type",
uotm: &UserOAuthTokenManager{},
args: args{
ctx: context.Background(),
},
setup: func(t *testing.T) {
tokenInfoJSON := `{
"access_token": "dummy_access_token",
"refresh_token": "dummy_refresh_token",
"expires_in": 0,
"expires_on": 0,
"not_before": 0,
"resource": "dummy_resource",
"token_type": "dummy_token_type",
"_tenant": "dummy_tenant",
"_ad_endpoint": "dummy_ad_endpoint",
"_token_refresh_source": 255,
"_application_id": "dummy_application_id",
"IdentityInfo": {
"_identity_client_id": "dummy_identity_client_id",
"_identity_object_id": "dummy_identity_object_id",
"_identity_msi_res_id": "dummy_identity_msi_res_id"
},
"SPNInfo": {
"_spn_secret": "dummy_spn_secret",
"_spn_cert_path": "dummy_spn_cert_path"
}
}`

// Set the environment variable AZCOPY_OAUTH_TOKEN_INFO
err := os.Setenv("AZCOPY_OAUTH_TOKEN_INFO", tokenInfoJSON)
if err != nil {
t.Fatalf("Failed to set environment variable: %v", err)
}
},
want: &OAuthTokenInfo{
Tenant: "dummy_tenant",
ActiveDirectoryEndpoint: "dummy_ad_endpoint",
LoginType: 255,
ApplicationID: "dummy_application_id",
IdentityInfo: IdentityInfo{
ClientID: "dummy_identity_client_id",
ObjectID: "dummy_identity_object_id",
MSIResID: "dummy_identity_msi_res_id",
},
SPNInfo: SPNInfo{
Secret: "dummy_spn_secret",
CertPath: "dummy_spn_cert_path",
},
},
wantErr: false,
},
{
name: "This UT tests if _token_refresh_source fails to parse due to invalid type",
uotm: &UserOAuthTokenManager{},
args: args{
ctx: context.Background(),
},
setup: func(t *testing.T) {
tokenInfoJSON := `{
"access_token": "dummy_access_token",
"refresh_token": "dummy_refresh_token",
"expires_in": 0,
"expires_on": 0,
"not_before": 0,
"resource": "dummy_resource",
"token_type": "dummy_token_type",
"_tenant": "dummy_tenant",
"_ad_endpoint": "dummy_ad_endpoint",
"_token_refresh_source": 2er25,
"_application_id": "dummy_application_id",
"IdentityInfo": {
"_identity_client_id": "dummy_identity_client_id",
"_identity_object_id": "dummy_identity_object_id",
"_identity_msi_res_id": "dummy_identity_msi_res_id"
},
"SPNInfo": {
"_spn_secret": "dummy_spn_secret",
"_spn_cert_path": "dummy_spn_cert_path"
}
}`

// Set the environment variable AZCOPY_OAUTH_TOKEN_INFO
err := os.Setenv("AZCOPY_OAUTH_TOKEN_INFO", tokenInfoJSON)
if err != nil {
t.Fatalf("Failed to set environment variable: %v", err)
}
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

tt.setup(t)
got, err := tt.uotm.GetTokenInfo(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("UserOAuthTokenManager.GetTokenInfo() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != nil && reflect.DeepEqual(got, tt.want) {
t.Errorf("UserOAuthTokenManager.GetTokenInfo() = %v, want %v", got, tt.want)
}
})
}
}
Loading