|
|
@@ -31,6 +31,7 @@ import (
|
|
|
|
|
|
"github.com/Azure/go-autorest/autorest"
|
|
|
"github.com/Azure/go-autorest/autorest/adal"
|
|
|
+ auth2 "github.com/Azure/go-autorest/autorest/azure/auth"
|
|
|
"github.com/Azure/go-autorest/autorest/azure/cli"
|
|
|
"github.com/Azure/go-autorest/autorest/date"
|
|
|
"github.com/pkg/errors"
|
|
|
@@ -93,6 +94,31 @@ func newAzureLoginServiceFromPath(tokenStorePath string, helper apiHelper) (Azur
|
|
|
}, nil
|
|
|
}
|
|
|
|
|
|
+// LoginFromServicePrincipal login with clientId / clientSecret from a previously created service principal
|
|
|
+func (login AzureLoginService) LoginFromServicePrincipal(clientID string, clientSecret string, tenantID string) error {
|
|
|
+ // Tried with auth2.NewUsernamePasswordConfig() but could not make this work with username / password, setting this for CI with clientID / clientSecret
|
|
|
+ creds := auth2.NewClientCredentialsConfig(clientID, clientSecret, tenantID)
|
|
|
+
|
|
|
+ spToken, err := creds.ServicePrincipalToken()
|
|
|
+ if err != nil {
|
|
|
+ return errors.Wrapf(errdefs.ErrLoginFailed, "could not login with service principal: %s", err)
|
|
|
+ }
|
|
|
+ err = spToken.Refresh()
|
|
|
+ if err != nil {
|
|
|
+ return errors.Wrapf(errdefs.ErrLoginFailed, "could not login with service principal: %s", err)
|
|
|
+ }
|
|
|
+ token, err := spToOAuthToken(spToken.Token())
|
|
|
+ if err != nil {
|
|
|
+ return errors.Wrapf(errdefs.ErrLoginFailed, "could not read service principal token expiry: %s", err)
|
|
|
+ }
|
|
|
+ loginInfo := TokenInfo{TenantID: tenantID, Token: token}
|
|
|
+
|
|
|
+ if err := login.tokenStore.writeLoginInfo(loginInfo); err != nil {
|
|
|
+ return errors.Wrapf(errdefs.ErrLoginFailed, "could not store login info: %s", err)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
// Login performs an Azure login through a web browser
|
|
|
func (login AzureLoginService) Login(ctx context.Context) error {
|
|
|
queryCh := make(chan localResponse, 1)
|
|
|
@@ -179,6 +205,21 @@ func toOAuthToken(token azureToken) oauth2.Token {
|
|
|
return oauthToken
|
|
|
}
|
|
|
|
|
|
+func spToOAuthToken(token adal.Token) (oauth2.Token, error) {
|
|
|
+ expiresIn, err := token.ExpiresIn.Int64()
|
|
|
+ if err != nil {
|
|
|
+ return oauth2.Token{}, err
|
|
|
+ }
|
|
|
+ expireTime := time.Now().Add(time.Duration(expiresIn) * time.Second)
|
|
|
+ oauthToken := oauth2.Token{
|
|
|
+ RefreshToken: token.RefreshToken,
|
|
|
+ AccessToken: token.AccessToken,
|
|
|
+ Expiry: expireTime,
|
|
|
+ TokenType: token.Type,
|
|
|
+ }
|
|
|
+ return oauthToken, nil
|
|
|
+}
|
|
|
+
|
|
|
// NewAuthorizerFromLogin creates an authorizer based on login access token
|
|
|
func NewAuthorizerFromLogin() (autorest.Authorizer, error) {
|
|
|
return newAuthorizerFromLoginStorePath(getTokenStorePath())
|