github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/sys/it/impl_signupin_test.go (about)

     1  /*
     2   * Copyright (c) 2020-present unTill Pro, Ltd.
     3   */
     4  
     5  package sys_it
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/voedger/voedger/pkg/istructs"
    15  	payloads "github.com/voedger/voedger/pkg/itokens-payloads"
    16  	coreutils "github.com/voedger/voedger/pkg/utils"
    17  	it "github.com/voedger/voedger/pkg/vit"
    18  )
    19  
    20  func TestBasicUsage_SignUpIn(t *testing.T) {
    21  	require := require.New(t)
    22  	vit := it.NewVIT(t, &it.SharedConfig_App1)
    23  	defer vit.TearDown()
    24  	loginName1 := vit.NextName()
    25  	loginName2 := vit.NextName()
    26  
    27  	login1 := vit.SignUp(loginName1, "pwd1", istructs.AppQName_test1_app1)
    28  	login2 := vit.SignUp(loginName2, "pwd2", istructs.AppQName_test1_app1) // now wrong to create a login in a different CLusterID because it is unknown how to init AppWorkspace there
    29  
    30  	prn1 := vit.SignIn(login1)
    31  	prn2 := vit.SignIn(login2)
    32  
    33  	require.NotEqual(prn1.Token, prn2.Token)
    34  	require.Equal(istructs.ClusterID(1), prn1.ProfileWSID.ClusterID())
    35  	require.Equal(istructs.ClusterID(1), prn2.ProfileWSID.ClusterID())
    36  	require.True(prn1.ProfileWSID.BaseWSID() >= istructs.FirstBaseUserWSID &&
    37  		prn2.ProfileWSID.BaseWSID() >= istructs.FirstBaseUserWSID &&
    38  		prn1.ProfileWSID.BaseWSID() != prn2.ProfileWSID.BaseWSID())
    39  
    40  	// refresh principal token
    41  	// simulate delay to make the new token be different
    42  	vit.TimeAdd(time.Minute)
    43  	body := `{"args":{},"elements":[{"fields":["NewPrincipalToken"]}]}`
    44  	resp := vit.PostProfile(prn1, "q.sys.RefreshPrincipalToken", body)
    45  
    46  	refreshedPrincipalToken := resp.SectionRow()[0].(string)
    47  	require.NotEqual(prn1.Token, refreshedPrincipalToken)
    48  
    49  	// читать CDoc<Login> не надо. И вообще, в AppWS делать нечего
    50  
    51  	var idOfCDocUserProfile int64
    52  	t.Run("check CDoc<sys.UserProfile> at profileWSID at target app at target cluster", func(t *testing.T) {
    53  		body := `{"args":{"Schema":"sys.UserProfile"},"elements":[{"fields":["sys.ID", "DisplayName"]}]}`
    54  		resp := vit.PostProfile(prn1, "q.sys.Collection", body)
    55  		require.Equal("User Name", resp.SectionRow()[1])
    56  		idOfCDocUserProfile = int64(resp.SectionRow()[0].(float64))
    57  	})
    58  
    59  	// checking CDoc<sys.UserProfile> creation is senceless because: in wsid 1 -> 403 foridden + workspace is not initialized, in profile wsid -> singleton violation
    60  
    61  	t.Run("modify CDoc<sys.UserProfile> after creation", func(t *testing.T) {
    62  		body := fmt.Sprintf(`{"cuds": [{"sys.ID": %d,"fields": {"DisplayName":"new name"}}]}`, idOfCDocUserProfile)
    63  		vit.PostProfile(prn1, "c.sys.CUD", body) // nothing to check, just expect no errors here
    64  	})
    65  }
    66  
    67  func TestCreateLoginErrors(t *testing.T) {
    68  	vit := it.NewVIT(t, &it.SharedConfig_App1)
    69  	defer vit.TearDown()
    70  
    71  	t.Run("wrong AppWSID", func(t *testing.T) {
    72  		body := fmt.Sprintf(`{"args":{"Login":"login1","AppName":"test1/app1","SubjectKind":%d,"WSKindInitializationData":"{}","ProfileCluster":1},"unloggedArgs":{"Password":"password"}}`, istructs.SubjectKind_User)
    73  		crc16 := coreutils.CRC16([]byte("login1")) - 1 // simulate crc16 is calculated wrong
    74  		pseudoWSID := istructs.NewWSID(istructs.MainClusterID, istructs.WSID(crc16))
    75  		resp := vit.PostApp(istructs.AppQName_sys_registry, pseudoWSID, "c.registry.CreateLogin", body, coreutils.Expect403())
    76  		resp.RequireError(t, "wrong AppWSID: 140737488420870 expected, 140737488420869 got")
    77  	})
    78  
    79  	login := vit.NextName()
    80  	loginPseudoWSID := coreutils.GetPseudoWSID(istructs.NullWSID, login, istructs.MainClusterID)
    81  
    82  	t.Run("unknown application", func(t *testing.T) {
    83  		body := fmt.Sprintf(`{"args":{"Login":"%s","AppName":"my/unknown","SubjectKind":%d,"WSKindInitializationData":"{}","ProfileCluster":%d},"unloggedArgs":{"Password":"password"}}`,
    84  			login, istructs.SubjectKind_User, istructs.MainClusterID)
    85  		resp := vit.PostApp(istructs.AppQName_sys_registry, loginPseudoWSID, "c.registry.CreateLogin", body, coreutils.Expect400())
    86  		resp.RequireError(t, "unknown application my/unknown")
    87  	})
    88  
    89  	t.Run("wrong application name", func(t *testing.T) {
    90  		body := fmt.Sprintf(`{"args":{"Login":"%s","AppName":"wrong-AppName","SubjectKind":%d,"WSKindInitializationData":"{}","ProfileCluster":1},"unloggedArgs":{"Password":"different"}}`,
    91  			login, istructs.SubjectKind_User)
    92  		resp := vit.PostApp(istructs.AppQName_sys_registry, loginPseudoWSID, "c.registry.CreateLogin", body, coreutils.Expect400())
    93  		resp.RequireContainsError(t, "failed to parse app qualified name")
    94  	})
    95  
    96  	newLogin := vit.SignUp(login, "1", istructs.AppQName_test1_app1)
    97  	// wait for acomplishing the profile init
    98  	vit.SignIn(newLogin)
    99  
   100  	t.Run("create an existing login again", func(t *testing.T) {
   101  		vit.SignUp(login, "1", istructs.AppQName_test1_app1, it.WithReqOpt(coreutils.Expect409()))
   102  	})
   103  
   104  	t.Run("subject name constraint violation", func(t *testing.T) {
   105  		// see https://dev.untill.com/projects/#!537026
   106  		wrongLogins := []string{
   107  			"вронг",
   108  			"test@tesT.com",
   109  			"test@test.com ",
   110  			" test@test.com",
   111  			" test@test.com ",
   112  			".test@test.com",
   113  			"test@test.com.",
   114  			".test@test.com.",
   115  			"test@test..com",
   116  			"-test@test.com",
   117  			"test@test.com-",
   118  			"-test@test.com",
   119  			"-test@test.com-",
   120  		}
   121  		for _, wrongLogin := range wrongLogins {
   122  			pseudoWSID := coreutils.GetPseudoWSID(istructs.NullWSID, wrongLogin, istructs.MainClusterID)
   123  			body := fmt.Sprintf(`{"args":{"Login":"%s","AppName":"%s","SubjectKind":%d,"WSKindInitializationData":"{}","ProfileCluster":%d},"unloggedArgs":{"Password":"%s"}}`,
   124  				wrongLogin, istructs.AppQName_test1_app1.String(), istructs.SubjectKind_User, istructs.MainClusterID, "1")
   125  			resp := vit.PostApp(istructs.AppQName_sys_registry, pseudoWSID, "c.registry.CreateLogin", body, coreutils.Expect400())
   126  			resp.RequireContainsError(t, "incorrect login format")
   127  		}
   128  	})
   129  }
   130  
   131  func TestSignInErrors(t *testing.T) {
   132  	vit := it.NewVIT(t, &it.SharedConfig_App1)
   133  	defer vit.TearDown()
   134  
   135  	login := vit.NextName()
   136  	pseudoWSID := coreutils.GetPseudoWSID(istructs.NullWSID, login, istructs.MainClusterID)
   137  
   138  	t.Run("unknown login", func(t *testing.T) {
   139  		body := fmt.Sprintf(`{"args": {"Login": "%s","Password": "1","AppName": "%s"},"elements":[{"fields":["PrincipalToken", "WSID", "WSError"]}]}`,
   140  			login, istructs.AppQName_test1_app1.String())
   141  		vit.PostApp(istructs.AppQName_sys_registry, pseudoWSID, "q.registry.IssuePrincipalToken", body, coreutils.Expect401()).Println()
   142  	})
   143  
   144  	newLogin := vit.SignUp(login, "1", istructs.AppQName_test1_app1)
   145  	// wait for acomplishing the profile init
   146  	vit.SignIn(newLogin)
   147  
   148  	t.Run("wrong password", func(t *testing.T) {
   149  		body := fmt.Sprintf(`{"args": {"Login": "%s","Password": "wrongPass","AppName": "%s"},"elements":[{"fields":[]}]}`,
   150  			login, istructs.AppQName_test1_app1.String())
   151  		vit.PostApp(istructs.AppQName_sys_registry, pseudoWSID, "q.registry.IssuePrincipalToken", body, coreutils.Expect401()).Println()
   152  	})
   153  }
   154  
   155  func TestDeviceProfile(t *testing.T) {
   156  	require := require.New(t)
   157  	vit := it.NewVIT(t, &it.SharedConfig_App1)
   158  	defer vit.TearDown()
   159  	loginName := vit.NextName()
   160  	deviceLogin := vit.SignUpDevice(loginName, "123", istructs.AppQName_test1_app2)
   161  	devicePrn := vit.SignIn(deviceLogin)
   162  	as, err := vit.AppStructs(istructs.AppQName_test1_app2)
   163  	require.NoError(err)
   164  	devicePrnPayload := payloads.PrincipalPayload{}
   165  	_, err = as.AppTokens().ValidateToken(devicePrn.Token, &devicePrnPayload)
   166  	require.NoError(err)
   167  	require.Equal(istructs.SubjectKind_Device, devicePrnPayload.SubjectKind)
   168  
   169  	t.Run("exec a simple operation in the device profile", func(t *testing.T) {
   170  		body := `{"args":{"Schema":"sys.WorkspaceDescriptor"},"elements":[{"fields":["sys.ID"]}]}`
   171  		vit.PostProfile(devicePrn, "q.sys.Collection", body)
   172  	})
   173  
   174  	t.Run("refresh the device principal token", func(t *testing.T) {
   175  		// simulate delay to make the new token be different
   176  		vit.TimeAdd(time.Minute)
   177  		body := `{"args":{},"elements":[{"fields":["NewPrincipalToken"]}]}`
   178  		resp := vit.PostProfile(devicePrn, "q.sys.RefreshPrincipalToken", body)
   179  		require.NotEqual(devicePrn.Token, resp.SectionRow()[0].(string))
   180  	})
   181  
   182  }