mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-10 21:47:13 +08:00
kubernetes: enable azure auth
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
191
vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE
generated
vendored
Normal file
191
vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015 Microsoft Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
292
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
Normal file
292
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
Normal file
@ -0,0 +1,292 @@
|
||||
# Azure Active Directory authentication for Go
|
||||
|
||||
This is a standalone package for authenticating with Azure Active
|
||||
Directory from other Go libraries and applications, in particular the [Azure SDK
|
||||
for Go](https://github.com/Azure/azure-sdk-for-go).
|
||||
|
||||
Note: Despite the package's name it is not related to other "ADAL" libraries
|
||||
maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues
|
||||
should be opened in [this repo's](https://github.com/Azure/go-autorest/issues)
|
||||
or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue
|
||||
trackers.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get -u github.com/Azure/go-autorest/autorest/adal
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
|
||||
|
||||
### Register an Azure AD Application with secret
|
||||
|
||||
|
||||
1. Register a new application with a `secret` credential
|
||||
|
||||
```
|
||||
az ad app create \
|
||||
--display-name example-app \
|
||||
--homepage https://example-app/home \
|
||||
--identifier-uris https://example-app/app \
|
||||
--password secret
|
||||
```
|
||||
|
||||
2. Create a service principal using the `Application ID` from previous step
|
||||
|
||||
```
|
||||
az ad sp create --id "Application ID"
|
||||
```
|
||||
|
||||
* Replace `Application ID` with `appId` from step 1.
|
||||
|
||||
### Register an Azure AD Application with certificate
|
||||
|
||||
1. Create a private key
|
||||
|
||||
```
|
||||
openssl genrsa -out "example-app.key" 2048
|
||||
```
|
||||
|
||||
2. Create the certificate
|
||||
|
||||
```
|
||||
openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr"
|
||||
openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000
|
||||
```
|
||||
|
||||
3. Create the PKCS12 version of the certificate containing also the private key
|
||||
|
||||
```
|
||||
openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass:
|
||||
|
||||
```
|
||||
|
||||
4. Register a new application with the certificate content form `example-app.crt`
|
||||
|
||||
```
|
||||
certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)"
|
||||
|
||||
az ad app create \
|
||||
--display-name example-app \
|
||||
--homepage https://example-app/home \
|
||||
--identifier-uris https://example-app/app \
|
||||
--key-usage Verify --end-date 2018-01-01 \
|
||||
--key-value "${certificateContents}"
|
||||
```
|
||||
|
||||
5. Create a service principal using the `Application ID` from previous step
|
||||
|
||||
```
|
||||
az ad sp create --id "APPLICATION_ID"
|
||||
```
|
||||
|
||||
* Replace `APPLICATION_ID` with `appId` from step 4.
|
||||
|
||||
|
||||
### Grant the necessary permissions
|
||||
|
||||
Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained
|
||||
level. There is a set of [pre-defined roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles)
|
||||
which can be assigned to a service principal of an Azure AD application depending of your needs.
|
||||
|
||||
```
|
||||
az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME"
|
||||
```
|
||||
|
||||
* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step.
|
||||
* Replace the `ROLE_NAME` with a role name of your choice.
|
||||
|
||||
It is also possible to define custom role definitions.
|
||||
|
||||
```
|
||||
az role definition create --role-definition role-definition.json
|
||||
```
|
||||
|
||||
* Check [custom roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file.
|
||||
|
||||
|
||||
### Acquire Access Token
|
||||
|
||||
The common configuration used by all flows:
|
||||
|
||||
```Go
|
||||
const activeDirectoryEndpoint = "https://login.microsoftonline.com/"
|
||||
tenantID := "TENANT_ID"
|
||||
oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID)
|
||||
|
||||
applicationID := "APPLICATION_ID"
|
||||
|
||||
callback := func(token adal.Token) error {
|
||||
// This is called after the token is acquired
|
||||
}
|
||||
|
||||
// The resource for which the token is acquired
|
||||
resource := "https://management.core.windows.net/"
|
||||
```
|
||||
|
||||
* Replace the `TENANT_ID` with your tenant ID.
|
||||
* Replace the `APPLICATION_ID` with the value from previous section.
|
||||
|
||||
#### Client Credentials
|
||||
|
||||
```Go
|
||||
applicationSecret := "APPLICATION_SECRET"
|
||||
|
||||
spt, err := adal.NewServicePrincipalToken(
|
||||
*oauthConfig,
|
||||
appliationID,
|
||||
applicationSecret,
|
||||
resource,
|
||||
callbacks...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Acquire a new access token
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
* Replace the `APPLICATION_SECRET` with the `password` value from previous section.
|
||||
|
||||
#### Client Certificate
|
||||
|
||||
```Go
|
||||
certificatePath := "./example-app.pfx"
|
||||
|
||||
certData, err := ioutil.ReadFile(certificatePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err)
|
||||
}
|
||||
|
||||
// Get the certificate and private key from pfx file
|
||||
certificate, rsaPrivateKey, err := decodePkcs12(certData, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromCertificate(
|
||||
*oauthConfig,
|
||||
applicationID,
|
||||
certificate,
|
||||
rsaPrivateKey,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
// Acquire a new access token
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
* Update the certificate path to point to the example-app.pfx file which was created in previous section.
|
||||
|
||||
|
||||
#### Device Code
|
||||
|
||||
```Go
|
||||
oauthClient := &http.Client{}
|
||||
|
||||
// Acquire the device code
|
||||
deviceCode, err := adal.InitiateDeviceAuth(
|
||||
oauthClient,
|
||||
*oauthConfig,
|
||||
applicationID,
|
||||
resource)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to start device auth flow: %s", err)
|
||||
}
|
||||
|
||||
// Display the authentication message
|
||||
fmt.Println(*deviceCode.Message)
|
||||
|
||||
// Wait here until the user is authenticated
|
||||
token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to finish device auth flow: %s", err)
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromManualToken(
|
||||
*oauthConfig,
|
||||
applicationID,
|
||||
resource,
|
||||
*token,
|
||||
callbacks...)
|
||||
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
#### Username password authenticate
|
||||
|
||||
```Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
|
||||
*oauthConfig,
|
||||
applicationID,
|
||||
username,
|
||||
password,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
#### Authorization code authenticate
|
||||
|
||||
``` Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
|
||||
*oauthConfig,
|
||||
applicationID,
|
||||
clientSecret,
|
||||
authorizationCode,
|
||||
redirectURI,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
### Command Line Tool
|
||||
|
||||
A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
|
||||
|
||||
```
|
||||
adal -h
|
||||
|
||||
Usage of ./adal:
|
||||
-applicationId string
|
||||
application id
|
||||
-certificatePath string
|
||||
path to pk12/PFC application certificate
|
||||
-mode string
|
||||
authentication mode (device, secret, cert, refresh) (default "device")
|
||||
-resource string
|
||||
resource for which the token is requested
|
||||
-secret string
|
||||
application secret
|
||||
-tenantId string
|
||||
tenant id
|
||||
-tokenCachePath string
|
||||
location of oath token cache (default "/home/cgc/.adal/accessToken.json")
|
||||
```
|
||||
|
||||
Example acquire a token for `https://management.core.windows.net/` using device code flow:
|
||||
|
||||
```
|
||||
adal -mode device \
|
||||
-applicationId "APPLICATION_ID" \
|
||||
-tenantId "TENANT_ID" \
|
||||
-resource https://management.core.windows.net/
|
||||
|
||||
```
|
151
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
Normal file
151
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
activeDirectoryEndpointTemplate = "%s/oauth2/%s%s"
|
||||
)
|
||||
|
||||
// OAuthConfig represents the endpoints needed
|
||||
// in OAuth operations
|
||||
type OAuthConfig struct {
|
||||
AuthorityEndpoint url.URL `json:"authorityEndpoint"`
|
||||
AuthorizeEndpoint url.URL `json:"authorizeEndpoint"`
|
||||
TokenEndpoint url.URL `json:"tokenEndpoint"`
|
||||
DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"`
|
||||
}
|
||||
|
||||
// IsZero returns true if the OAuthConfig object is zero-initialized.
|
||||
func (oac OAuthConfig) IsZero() bool {
|
||||
return oac == OAuthConfig{}
|
||||
}
|
||||
|
||||
func validateStringParam(param, name string) error {
|
||||
if len(param) == 0 {
|
||||
return fmt.Errorf("parameter '" + name + "' cannot be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewOAuthConfig returns an OAuthConfig with tenant specific urls
|
||||
func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
||||
apiVer := "1.0"
|
||||
return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer)
|
||||
}
|
||||
|
||||
// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls.
|
||||
// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value.
|
||||
func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) {
|
||||
if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api := ""
|
||||
// it's legal for tenantID to be empty so don't validate it
|
||||
if apiVersion != nil {
|
||||
if err := validateStringParam(*apiVersion, "apiVersion"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api = fmt.Sprintf("?api-version=%s", *apiVersion)
|
||||
}
|
||||
u, err := url.Parse(activeDirectoryEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorityURL, err := u.Parse(tenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OAuthConfig{
|
||||
AuthorityEndpoint: *authorityURL,
|
||||
AuthorizeEndpoint: *authorizeURL,
|
||||
TokenEndpoint: *tokenURL,
|
||||
DeviceCodeEndpoint: *deviceCodeURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MultiTenantOAuthConfig provides endpoints for primary and aulixiary tenant IDs.
|
||||
type MultiTenantOAuthConfig interface {
|
||||
PrimaryTenant() *OAuthConfig
|
||||
AuxiliaryTenants() []*OAuthConfig
|
||||
}
|
||||
|
||||
// OAuthOptions contains optional OAuthConfig creation arguments.
|
||||
type OAuthOptions struct {
|
||||
APIVersion string
|
||||
}
|
||||
|
||||
func (c OAuthOptions) apiVersion() string {
|
||||
if c.APIVersion != "" {
|
||||
return fmt.Sprintf("?api-version=%s", c.APIVersion)
|
||||
}
|
||||
return "1.0"
|
||||
}
|
||||
|
||||
// NewMultiTenantOAuthConfig creates an object that support multitenant OAuth configuration.
|
||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/authenticate-multi-tenant for more information.
|
||||
func NewMultiTenantOAuthConfig(activeDirectoryEndpoint, primaryTenantID string, auxiliaryTenantIDs []string, options OAuthOptions) (MultiTenantOAuthConfig, error) {
|
||||
if len(auxiliaryTenantIDs) == 0 || len(auxiliaryTenantIDs) > 3 {
|
||||
return nil, errors.New("must specify one to three auxiliary tenants")
|
||||
}
|
||||
mtCfg := multiTenantOAuthConfig{
|
||||
cfgs: make([]*OAuthConfig, len(auxiliaryTenantIDs)+1),
|
||||
}
|
||||
apiVer := options.apiVersion()
|
||||
pri, err := NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, primaryTenantID, &apiVer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create OAuthConfig for primary tenant: %v", err)
|
||||
}
|
||||
mtCfg.cfgs[0] = pri
|
||||
for i := range auxiliaryTenantIDs {
|
||||
aux, err := NewOAuthConfig(activeDirectoryEndpoint, auxiliaryTenantIDs[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create OAuthConfig for tenant '%s': %v", auxiliaryTenantIDs[i], err)
|
||||
}
|
||||
mtCfg.cfgs[i+1] = aux
|
||||
}
|
||||
return mtCfg, nil
|
||||
}
|
||||
|
||||
type multiTenantOAuthConfig struct {
|
||||
// first config in the slice is the primary tenant
|
||||
cfgs []*OAuthConfig
|
||||
}
|
||||
|
||||
func (m multiTenantOAuthConfig) PrimaryTenant() *OAuthConfig {
|
||||
return m.cfgs[0]
|
||||
}
|
||||
|
||||
func (m multiTenantOAuthConfig) AuxiliaryTenants() []*OAuthConfig {
|
||||
return m.cfgs[1:]
|
||||
}
|
273
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
Normal file
273
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
This file is largely based on rjw57/oauth2device's code, with the follow differences:
|
||||
* scope -> resource, and only allow a single one
|
||||
* receive "Message" in the DeviceCode struct and show it to users as the prompt
|
||||
* azure-xplat-cli has the following behavior that this emulates:
|
||||
- does not send client_secret during the token exchange
|
||||
- sends resource again in the token exchange request
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "autorest/adal/devicetoken:"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow
|
||||
ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix)
|
||||
|
||||
// ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow
|
||||
ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix)
|
||||
|
||||
// ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow
|
||||
ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix)
|
||||
|
||||
// ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow
|
||||
ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix)
|
||||
|
||||
// ErrDeviceSlowDown represents the service telling us we're polling too often during device flow
|
||||
ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix)
|
||||
|
||||
// ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow
|
||||
ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix)
|
||||
|
||||
// ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow
|
||||
ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix)
|
||||
|
||||
errCodeSendingFails = "Error occurred while sending request for Device Authorization Code"
|
||||
errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint"
|
||||
errTokenSendingFails = "Error occurred while sending request with device code for a token"
|
||||
errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)"
|
||||
errStatusNotOK = "Error HTTP status != 200"
|
||||
)
|
||||
|
||||
// DeviceCode is the object returned by the device auth endpoint
|
||||
// It contains information to instruct the user to complete the auth flow
|
||||
type DeviceCode struct {
|
||||
DeviceCode *string `json:"device_code,omitempty"`
|
||||
UserCode *string `json:"user_code,omitempty"`
|
||||
VerificationURL *string `json:"verification_url,omitempty"`
|
||||
ExpiresIn *int64 `json:"expires_in,string,omitempty"`
|
||||
Interval *int64 `json:"interval,string,omitempty"`
|
||||
|
||||
Message *string `json:"message"` // Azure specific
|
||||
Resource string // store the following, stored when initiating, used when exchanging
|
||||
OAuthConfig OAuthConfig
|
||||
ClientID string
|
||||
}
|
||||
|
||||
// TokenError is the object returned by the token exchange endpoint
|
||||
// when something is amiss
|
||||
type TokenError struct {
|
||||
Error *string `json:"error,omitempty"`
|
||||
ErrorCodes []int `json:"error_codes,omitempty"`
|
||||
ErrorDescription *string `json:"error_description,omitempty"`
|
||||
Timestamp *string `json:"timestamp,omitempty"`
|
||||
TraceID *string `json:"trace_id,omitempty"`
|
||||
}
|
||||
|
||||
// DeviceToken is the object return by the token exchange endpoint
|
||||
// It can either look like a Token or an ErrorToken, so put both here
|
||||
// and check for presence of "Error" to know if we are in error state
|
||||
type deviceToken struct {
|
||||
Token
|
||||
TokenError
|
||||
}
|
||||
|
||||
// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode
|
||||
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
|
||||
// Deprecated: use InitiateDeviceAuthWithContext() instead.
|
||||
func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
||||
return InitiateDeviceAuthWithContext(context.Background(), sender, oauthConfig, clientID, resource)
|
||||
}
|
||||
|
||||
// InitiateDeviceAuthWithContext initiates a device auth flow. It returns a DeviceCode
|
||||
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
|
||||
func InitiateDeviceAuthWithContext(ctx context.Context, sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
||||
v := url.Values{
|
||||
"client_id": []string{clientID},
|
||||
"resource": []string{resource},
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
||||
}
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
resp, err := sender.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK)
|
||||
}
|
||||
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, ErrDeviceCodeEmpty
|
||||
}
|
||||
|
||||
var code DeviceCode
|
||||
err = json.Unmarshal(rb, &code)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
code.ClientID = clientID
|
||||
code.Resource = resource
|
||||
code.OAuthConfig = oauthConfig
|
||||
|
||||
return &code, nil
|
||||
}
|
||||
|
||||
// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint
|
||||
// to see if the device flow has: been completed, timed out, or otherwise failed
|
||||
// Deprecated: use CheckForUserCompletionWithContext() instead.
|
||||
func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
||||
return CheckForUserCompletionWithContext(context.Background(), sender, code)
|
||||
}
|
||||
|
||||
// CheckForUserCompletionWithContext takes a DeviceCode and checks with the Azure AD OAuth endpoint
|
||||
// to see if the device flow has: been completed, timed out, or otherwise failed
|
||||
func CheckForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) {
|
||||
v := url.Values{
|
||||
"client_id": []string{code.ClientID},
|
||||
"code": []string{*code.DeviceCode},
|
||||
"grant_type": []string{OAuthGrantTypeDeviceCode},
|
||||
"resource": []string{code.Resource},
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
||||
}
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
resp, err := sender.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK)
|
||||
}
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, ErrOAuthTokenEmpty
|
||||
}
|
||||
|
||||
var token deviceToken
|
||||
err = json.Unmarshal(rb, &token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if token.Error == nil {
|
||||
return &token.Token, nil
|
||||
}
|
||||
|
||||
switch *token.Error {
|
||||
case "authorization_pending":
|
||||
return nil, ErrDeviceAuthorizationPending
|
||||
case "slow_down":
|
||||
return nil, ErrDeviceSlowDown
|
||||
case "access_denied":
|
||||
return nil, ErrDeviceAccessDenied
|
||||
case "code_expired":
|
||||
return nil, ErrDeviceCodeExpired
|
||||
default:
|
||||
// return a more meaningful error message if available
|
||||
if token.ErrorDescription != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, *token.Error, *token.ErrorDescription)
|
||||
}
|
||||
return nil, ErrDeviceGeneric
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs.
|
||||
// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
|
||||
// Deprecated: use WaitForUserCompletionWithContext() instead.
|
||||
func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
||||
return WaitForUserCompletionWithContext(context.Background(), sender, code)
|
||||
}
|
||||
|
||||
// WaitForUserCompletionWithContext calls CheckForUserCompletion repeatedly until a token is granted or an error
|
||||
// state occurs. This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
|
||||
func WaitForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) {
|
||||
intervalDuration := time.Duration(*code.Interval) * time.Second
|
||||
waitDuration := intervalDuration
|
||||
|
||||
for {
|
||||
token, err := CheckForUserCompletionWithContext(ctx, sender, code)
|
||||
|
||||
if err == nil {
|
||||
return token, nil
|
||||
}
|
||||
|
||||
switch err {
|
||||
case ErrDeviceSlowDown:
|
||||
waitDuration += waitDuration
|
||||
case ErrDeviceAuthorizationPending:
|
||||
// noop
|
||||
default: // everything else is "fatal" to us
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if waitDuration > (intervalDuration * 3) {
|
||||
return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(waitDuration):
|
||||
// noop
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
25
vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go
generated
vendored
Normal file
25
vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
//go:build modhack
|
||||
// +build modhack
|
||||
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file, and the github.com/Azure/go-autorest import, won't actually become part of
|
||||
// the resultant binary.
|
||||
|
||||
// Necessary for safely adding multi-module repo.
|
||||
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
||||
import _ "github.com/Azure/go-autorest"
|
135
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
Normal file
135
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/crypto/pkcs12"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrMissingCertificate is returned when no local certificate is found in the provided PFX data.
|
||||
ErrMissingCertificate = errors.New("adal: certificate missing")
|
||||
|
||||
// ErrMissingPrivateKey is returned when no private key is found in the provided PFX data.
|
||||
ErrMissingPrivateKey = errors.New("adal: private key missing")
|
||||
)
|
||||
|
||||
// LoadToken restores a Token object from a file located at 'path'.
|
||||
func LoadToken(path string) (*Token, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var token Token
|
||||
|
||||
dec := json.NewDecoder(file)
|
||||
if err = dec.Decode(&token); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err)
|
||||
}
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// SaveToken persists an oauth token at the given location on disk.
|
||||
// It moves the new file into place so it can safely be used to replace an existing file
|
||||
// that maybe accessed by multiple processes.
|
||||
func SaveToken(path string, mode os.FileMode, token Token) error {
|
||||
dir := filepath.Dir(path)
|
||||
err := os.MkdirAll(dir, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err)
|
||||
}
|
||||
|
||||
newFile, err := ioutil.TempFile(dir, "token")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create the temp file to write the token: %v", err)
|
||||
}
|
||||
tempPath := newFile.Name()
|
||||
|
||||
if err := json.NewEncoder(newFile).Encode(token); err != nil {
|
||||
return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err)
|
||||
}
|
||||
if err := newFile.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close temp file %s: %v", tempPath, err)
|
||||
}
|
||||
|
||||
// Atomic replace to avoid multi-writer file corruptions
|
||||
if err := os.Rename(tempPath, path); err != nil {
|
||||
return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err)
|
||||
}
|
||||
if err := os.Chmod(path, mode); err != nil {
|
||||
return fmt.Errorf("failed to chmod the token file %s: %v", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecodePfxCertificateData extracts the x509 certificate and RSA private key from the provided PFX data.
|
||||
// The PFX data must contain a private key along with a certificate whose public key matches that of the
|
||||
// private key or an error is returned.
|
||||
// If the private key is not password protected pass the empty string for password.
|
||||
func DecodePfxCertificateData(pfxData []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||
blocks, err := pkcs12.ToPEM(pfxData, password)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// first extract the private key
|
||||
var priv *rsa.PrivateKey
|
||||
for _, block := range blocks {
|
||||
if block.Type == "PRIVATE KEY" {
|
||||
priv, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if priv == nil {
|
||||
return nil, nil, ErrMissingPrivateKey
|
||||
}
|
||||
// now find the certificate with the matching public key of our private key
|
||||
var cert *x509.Certificate
|
||||
for _, block := range blocks {
|
||||
if block.Type == "CERTIFICATE" {
|
||||
pcert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
certKey, ok := pcert.PublicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
// keep looking
|
||||
continue
|
||||
}
|
||||
if priv.E == certKey.E && priv.N.Cmp(certKey.N) == 0 {
|
||||
// found a match
|
||||
cert = pcert
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if cert == nil {
|
||||
return nil, nil, ErrMissingCertificate
|
||||
}
|
||||
return cert, priv, nil
|
||||
}
|
101
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
Normal file
101
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
contentType = "Content-Type"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
||||
// DO NOT ACCESS THIS DIRECTLY. go through sender()
|
||||
var defaultSender Sender
|
||||
var defaultSenderInit = &sync.Once{}
|
||||
|
||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
||||
//
|
||||
// The standard http.Client conforms to this interface.
|
||||
type Sender interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// SenderFunc is a method that implements the Sender interface.
|
||||
type SenderFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Sender interface on SenderFunc.
|
||||
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
||||
return sf(r)
|
||||
}
|
||||
|
||||
// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the
|
||||
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
||||
// http.Response result.
|
||||
type SendDecorator func(Sender) Sender
|
||||
|
||||
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
||||
func CreateSender(decorators ...SendDecorator) Sender {
|
||||
return DecorateSender(sender(), decorators...)
|
||||
}
|
||||
|
||||
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
||||
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
||||
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
||||
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
||||
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
||||
for _, decorate := range decorators {
|
||||
s = decorate(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func sender() Sender {
|
||||
// note that we can't init defaultSender in init() since it will
|
||||
// execute before calling code has had a chance to enable tracing
|
||||
defaultSenderInit.Do(func() {
|
||||
// copied from http.DefaultTransport with a TLS minimum version.
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).DialContext,
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
},
|
||||
}
|
||||
var roundTripper http.RoundTripper = transport
|
||||
if tracing.IsEnabled() {
|
||||
roundTripper = tracing.NewTransport(transport)
|
||||
}
|
||||
j, _ := cookiejar.New(nil)
|
||||
defaultSender = &http.Client{Jar: j, Transport: roundTripper}
|
||||
})
|
||||
return defaultSender
|
||||
}
|
1328
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
Normal file
1328
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
76
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
Normal file
76
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
|
||||
tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
defer cancel()
|
||||
// http.NewRequestWithContext() was added in Go 1.13
|
||||
req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil)
|
||||
q := req.URL.Query()
|
||||
q.Add("api-version", msiAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
return sender.Do(req)
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
Normal file
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
|
||||
tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
defer cancel()
|
||||
req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil)
|
||||
req = req.WithContext(tempCtx)
|
||||
q := req.URL.Query()
|
||||
q.Add("api-version", msiAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
return sender.Do(req)
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
45
vendor/github.com/Azure/go-autorest/autorest/adal/version.go
generated
vendored
Normal file
45
vendor/github.com/Azure/go-autorest/autorest/adal/version.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package adal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const number = "v1.0.0"
|
||||
|
||||
var (
|
||||
ua = fmt.Sprintf("Go/%s (%s-%s) go-autorest/adal/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
number,
|
||||
)
|
||||
)
|
||||
|
||||
// UserAgent returns a string containing the Go version, system architecture and OS, and the adal version.
|
||||
func UserAgent() string {
|
||||
return ua
|
||||
}
|
||||
|
||||
// AddToUserAgent adds an extension to the current user agent
|
||||
func AddToUserAgent(extension string) error {
|
||||
if extension != "" {
|
||||
ua = fmt.Sprintf("%s %s", ua, extension)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Extension was empty, User Agent remained as '%s'", ua)
|
||||
}
|
Reference in New Issue
Block a user