|  | @@ -7,6 +7,7 @@ import (
 | 
	
		
			
				|  |  |  	"io/ioutil"
 | 
	
		
			
				|  |  |  	"log"
 | 
	
		
			
				|  |  |  	"math/rand"
 | 
	
		
			
				|  |  | +	"net"
 | 
	
		
			
				|  |  |  	"net/http"
 | 
	
		
			
				|  |  |  	"net/http/httputil"
 | 
	
		
			
				|  |  |  	"net/url"
 | 
	
	
		
			
				|  | @@ -97,20 +98,13 @@ type azureAPIHelper struct{}
 | 
	
		
			
				|  |  |  //Login perform azure login through browser
 | 
	
		
			
				|  |  |  func (login AzureLoginService) Login(ctx context.Context) error {
 | 
	
		
			
				|  |  |  	queryCh := make(chan url.Values, 1)
 | 
	
		
			
				|  |  | -	mux := http.NewServeMux()
 | 
	
		
			
				|  |  | -	mux.HandleFunc("/", queryHandler(queryCh))
 | 
	
		
			
				|  |  | -	server := &http.Server{Addr: ":8401", Handler: mux}
 | 
	
		
			
				|  |  | -	go func() {
 | 
	
		
			
				|  |  | -		if err := server.ListenAndServe(); err != nil {
 | 
	
		
			
				|  |  | -			queryCh <- url.Values{
 | 
	
		
			
				|  |  | -				"error": []string{fmt.Sprintf("error starting http server with: %v", err)},
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}()
 | 
	
		
			
				|  |  | +	serverPort, err := startLoginServer(queryCh)
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		return err
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	state := randomString("", 10)
 | 
	
		
			
				|  |  | -	authURL := fmt.Sprintf(authorizeFormat, clientID, "http://localhost:8401", state, scopes)
 | 
	
		
			
				|  |  | -	openbrowser(authURL)
 | 
	
		
			
				|  |  | +	redirectURL := "http://localhost:" + strconv.Itoa(serverPort)
 | 
	
		
			
				|  |  | +	openAzureLoginPage(redirectURL)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	select {
 | 
	
		
			
				|  |  |  	case <-ctx.Done():
 | 
	
	
		
			
				|  | @@ -129,7 +123,7 @@ func (login AzureLoginService) Login(ctx context.Context) error {
 | 
	
		
			
				|  |  |  			"client_id":    []string{clientID},
 | 
	
		
			
				|  |  |  			"code":         code,
 | 
	
		
			
				|  |  |  			"scope":        []string{scopes},
 | 
	
		
			
				|  |  | -			"redirect_uri": []string{"http://localhost:8401"},
 | 
	
		
			
				|  |  | +			"redirect_uri": []string{redirectURL},
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		token, err := login.apiHelper.queryToken(data, "organizations")
 | 
	
		
			
				|  |  |  		if err != nil {
 | 
	
	
		
			
				|  | @@ -183,6 +177,32 @@ func (login AzureLoginService) Login(ctx context.Context) error {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +func startLoginServer(queryCh chan url.Values) (int, error) {
 | 
	
		
			
				|  |  | +	mux := http.NewServeMux()
 | 
	
		
			
				|  |  | +	mux.HandleFunc("/", queryHandler(queryCh))
 | 
	
		
			
				|  |  | +	listener, err := net.Listen("tcp", ":0")
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		return 0, err
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	availablePort := listener.Addr().(*net.TCPAddr).Port
 | 
	
		
			
				|  |  | +	server := &http.Server{Handler: mux}
 | 
	
		
			
				|  |  | +	go func() {
 | 
	
		
			
				|  |  | +		if err := server.Serve(listener); err != nil {
 | 
	
		
			
				|  |  | +			queryCh <- url.Values{
 | 
	
		
			
				|  |  | +				"error": []string{fmt.Sprintf("error starting http server with: %v", err)},
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}()
 | 
	
		
			
				|  |  | +	return availablePort, nil
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func openAzureLoginPage(redirectURL string) {
 | 
	
		
			
				|  |  | +	state := randomString("", 10)
 | 
	
		
			
				|  |  | +	authURL := fmt.Sprintf(authorizeFormat, clientID, redirectURL, state, scopes)
 | 
	
		
			
				|  |  | +	openbrowser(authURL)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  func queryHandler(queryCh chan url.Values) func(w http.ResponseWriter, r *http.Request) {
 | 
	
		
			
				|  |  |  	queryHandler := func(w http.ResponseWriter, r *http.Request) {
 | 
	
		
			
				|  |  |  		_, hasCode := r.URL.Query()["code"]
 |