...

Source file src/github.com/okta/okta-sdk-golang/v2/tests/integration/authenticators_test.go

Documentation: github.com/okta/okta-sdk-golang/v2/tests/integration

     1  /*
     2   * Copyright 2018 - Present Okta, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package integration
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/okta/okta-sdk-golang/v2/okta"
    25  	"github.com/okta/okta-sdk-golang/v2/tests"
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  const (
    31  	PhoneNumberKey = "phone_number"
    32  	EmailKey       = "okta_email"
    33  )
    34  
    35  func TestListAuthenticators(t *testing.T) {
    36  	ctx, client, err := tests.NewClient(context.TODO())
    37  	require.NoError(t, err)
    38  
    39  	authenticators, resp, err := client.Authenticator.ListAuthenticators(ctx)
    40  	require.NoError(t, err)
    41  	assert.Equal(t, resp.StatusCode, 200, "List authenticators should have 200 status.")
    42  	assert.True(t, len(authenticators) > 0, "One or more authenticators should be present.")
    43  
    44  	_, err = pickAuthenticator(PhoneNumberKey, authenticators)
    45  	require.NoError(t, err, "There should at least be a phone authenticator.")
    46  }
    47  
    48  func TestGetAuthenticator(t *testing.T) {
    49  	ctx, client, err := tests.NewClient(context.TODO())
    50  	require.NoError(t, err)
    51  
    52  	phoneAuthenticator, err := fetchAuthenticator(PhoneNumberKey, ctx, client)
    53  	require.NoError(t, err)
    54  
    55  	authenticator, resp, err := client.Authenticator.GetAuthenticator(ctx, phoneAuthenticator.Id)
    56  	require.NoError(t, err)
    57  	assert.Equal(t, resp.StatusCode, 200, "Get authenticator should have 200 status.")
    58  	assert.Equal(t, authenticator.Id, phoneAuthenticator.Id, "Expected authenticator getter should equal phone authenticator.")
    59  }
    60  
    61  func TestUpdateAuthenticator(t *testing.T) {
    62  	ctx, client, err := tests.NewClient(context.TODO())
    63  	require.NoError(t, err)
    64  
    65  	emailAuthenticator, err := fetchAuthenticator(EmailKey, ctx, client)
    66  	require.NoError(t, err)
    67  
    68  	tokenLifetimeInMinutes := emailAuthenticator.Settings.TokenLifetimeInMinutes + 1
    69  	if tokenLifetimeInMinutes > 10 {
    70  		tokenLifetimeInMinutes = int64(5)
    71  	}
    72  
    73  	updateAuthenticator := okta.Authenticator{
    74  		Name: emailAuthenticator.Name,
    75  		Settings: &okta.AuthenticatorSettings{
    76  			TokenLifetimeInMinutes: tokenLifetimeInMinutes,
    77  		},
    78  	}
    79  	authenticator, resp, err := client.Authenticator.UpdateAuthenticator(ctx, emailAuthenticator.Id, okta.Authenticator(updateAuthenticator))
    80  	require.NoError(t, err)
    81  	assert.Equal(t, resp.StatusCode, 200)
    82  	assert.Equal(t, authenticator.Id, emailAuthenticator.Id)
    83  	assert.Equal(t, authenticator.Settings.TokenLifetimeInMinutes, tokenLifetimeInMinutes, "Expected authenticator token life in minutes to be updated.")
    84  }
    85  
    86  func TestActivateDeactivateAuthenticator(t *testing.T) {
    87  	t.Skip("Activating and deactiving the phone authenticator is flapping as other tests add that authenticator to policies.")
    88  
    89  	ctx, client, err := tests.NewClient(context.TODO())
    90  	require.NoError(t, err)
    91  
    92  	err = setupDisablePhoneNumberOnMFAEnrollPolicy()
    93  	require.NoError(t, err)
    94  
    95  	// Find the phone authenticator. Activate it if inactive, then deactivate
    96  	// it. Else, deactivate it, then activate it.
    97  	authenticator, err := fetchAuthenticator(PhoneNumberKey, ctx, client)
    98  	require.NoError(t, err)
    99  
   100  	var ops []string
   101  
   102  	if authenticator.Status == "INACTIVE" {
   103  		ops = []string{"activate", "deactivate"}
   104  	} else {
   105  		ops = []string{"deactivate", "activate"}
   106  	}
   107  
   108  	for _, op := range ops {
   109  		switch op {
   110  		case "activate":
   111  			result, _, err := client.Authenticator.ActivateAuthenticator(ctx, authenticator.Id)
   112  			require.NoError(t, err, "authenticator: "+authenticator.Id)
   113  			assert.Equal(t, "ACTIVE", result.Status, "Expected authenticator status to be active ("+authenticator.Id+").")
   114  		case "deactivate":
   115  			result, _, err := client.Authenticator.DeactivateAuthenticator(ctx, authenticator.Id)
   116  			require.NoError(t, err, "authenticator: "+authenticator.Id)
   117  			assert.Equal(t, "INACTIVE", result.Status, "Expected authenticator status to be inactive ("+authenticator.Id+").")
   118  		}
   119  	}
   120  }
   121  
   122  // pickAuthenticator helper to pick the phone authenticator from the
   123  // authenticators list
   124  func pickAuthenticator(key string, authenticators []*okta.Authenticator) (*okta.Authenticator, error) {
   125  	for _, authenticator := range authenticators {
   126  		if authenticator.Key == key {
   127  			return authenticator, nil
   128  		}
   129  	}
   130  
   131  	return nil, fmt.Errorf("%q authenticator not found", key)
   132  }
   133  
   134  // fetchAuthenticator helper to get the phone authenticator from the API
   135  func fetchAuthenticator(key string, ctx context.Context, client *okta.Client) (*okta.Authenticator, error) {
   136  	authenticators, _, err := client.Authenticator.ListAuthenticators(ctx)
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  	return pickAuthenticator(key, authenticators)
   141  }
   142  
   143  func setupDisablePhoneNumberOnMFAEnrollPolicy() error {
   144  	ctx, client, err := tests.NewClient(context.TODO())
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	rq := client.CloneRequestExecutor()
   150  	url := "/api/v1/policies?type=MFA_ENROLL"
   151  	req, err := rq.WithAccept("application/json").WithContentType("application/json").NewRequest("GET", url, nil)
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	var policies []interface{}
   157  	_, err = client.GetRequestExecutor().Do(ctx, req, &policies)
   158  	if err != nil {
   159  		return err
   160  	}
   161  
   162  	// note: updating policy settings directly using generic golang structs
   163  	policy := policies[0].(map[string]interface{})
   164  	if settings, ok := policy["settings"].(map[string]interface{}); ok {
   165  		if authenticators, ok := settings["authenticators"].([]interface{}); ok {
   166  			for _, authenticator := range authenticators {
   167  				key := authenticator.(map[string]interface{})["key"]
   168  				if key != "phone_number" {
   169  					continue
   170  				}
   171  				enroll := authenticator.(map[string]interface{})["enroll"].(map[string]interface{})
   172  				enroll["self"] = "NOT_ALLOWED"
   173  				break
   174  			}
   175  		}
   176  	}
   177  
   178  	url = fmt.Sprintf("/api/v1/policies/%s", policy["id"])
   179  	req, err = rq.WithAccept("application/json").WithContentType("application/json").NewRequest("PUT", url, policy)
   180  	if err != nil {
   181  		return err
   182  	}
   183  
   184  	// note: have executor read an interface to prevent a panic
   185  	var result interface{}
   186  	_, err = client.GetRequestExecutor().Do(ctx, req, &result)
   187  
   188  	return err
   189  }
   190  

View as plain text