func init() {
	logger.Init(ioutil.Discard, ioutil.Discard, ioutil.Discard, ioutil.Discard)
	privateKeyFilePath := flag.String("rsa-private", "./dist/key.private", "RSA private key file path")
	secureKeyFilePath := flag.String("secure-key", "./dist/secureKey", "password to encrypt the secure storage")
	usersDataPath := flag.String("data-file", "./dist/data.txt", "Login information file")
	flag.Parse()

	servicePath = cr.ServicePathPrefix + cr.Version + amPrefix
	resourcePath = listener + servicePath + usersPath

	usersList := en.New()
	signKey, verifyKey := app.SetupAToken(*privateKeyFilePath)
	loginKey := ss.GetSecureKey(*secureKeyFilePath)
	en.LoadInfo(*usersDataPath, loginKey, usersList)

	stRestful = libsecurityRestful.NewLibsecurityRestful()
	stRestful.SetData(usersList, loginKey, verifyKey, signKey, nil)

	rootCookieStr, _ := app.GenerateToken(defs.RootUserName, am.SuperUserPermission, false, clientIP, signKey)
	cr.TestSetCookie(rootCookieStr)

	for _, name := range usersName {
		stRestful.UsersList.AddUser(name)
	}

	go runServer()
	time.Sleep(100 * time.Millisecond)
}
// 1. Generate token and verify it is OK
// 2. As a root: Update the user privilege, verify the results
// 3. As a root: Update the user privilege to undefined previlege, verify the results are StatusBadRequest
// 4. As a root: Update the root privilege, verify that it is not allowed
// 5. As the user: Update the user privilege, verify that it is not allowed
func TestUpdatePrivilege(t *testing.T) {
	userName := usersName[0]

	initAListOfUsers(t, usersName)

	url := listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleAuthenticateCommand]), verifyPath)
	data := cr.StringMessage{Str: cr.GetMessageStr}
	exeCommandCheckRes(t, cr.HTTPGetStr, url, http.StatusOK, "", data)

	url = listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserPwdCommand]), usersPath, userName, privilegePath)
	okURLJ := cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, userName)}
	privilege, _ := json.Marshal(privilegePwd{Privilege: am.SuperUserPermission})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusCreated, string(privilege), okURLJ)

	privilege, _ = json.Marshal(privilegePwd{Privilege: "no p"})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusBadRequest, string(privilege), cr.Error{Code: http.StatusBadRequest})

	url = listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserPwdCommand]), usersPath, defs.RootUserName, privilegePath)
	okURLJ = cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, defs.RootUserName)}
	privilege, _ = json.Marshal(privilegePwd{Privilege: am.SuperUserPermission})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusBadRequest, string(privilege), cr.Error{Code: http.StatusBadRequest})

	cookieStr, _ := app.GenerateToken(userName, am.UserPermission, false, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusMethodNotAllowed, string(privilege), cr.Error{Code: http.StatusMethodNotAllowed})
}
// 1. As a root:
//	1.1 Reset user password
//	1.2 Success get user account info
//	1.3 Fail to reset root user password
// 2. As a user:
//	2.1 login with the new password
//	2.2 Fail to get account info
//	2.3 Change account password
//	2.4 Success get account info
func TestResetPassword(t *testing.T) {
	userName := usersName[0]
	updatedPwd := secretCode + "1"

	initAListOfUsers(t, usersName)
	// reset user password
	url := listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserCommand]), usersPath, userName)
	newPwd := exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusCreated, cr.GetMessageStr, cr.StringMessage{Str: cr.GetMessageStr})

	// fail to reset root user password
	url = listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserCommand]), usersPath, defs.RootUserName)
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusBadRequest, "", cr.Match{Match: false})

	// get user info
	url = resourcePath + "/" + userName
	data, _ := stRestful.UsersList.GetPropertyAttachedToEntity(userName, propertyName)
	exeCommandCheckRes(t, cr.HTTPGetStr, url, http.StatusOK, "", data.(*am.AmUserInfo))

	// login as user and fail to get user info
	d := data.(*am.AmUserInfo)
	cookieStr, _ := app.GenerateToken(userName, am.UserPermission, d.Pwd.TemporaryPwd, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)
	exeCommandCheckRes(t, cr.HTTPGetStr, url, http.StatusMethodNotAllowed, "", cr.Match{Match: false})

	var newPwdStr cr.Secret
	json.Unmarshal([]byte(newPwd), &newPwdStr)
	// update user account password
	url = listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserPwdCommand]), usersPath, userName, pwdPath)
	okURLJ := cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, userName)}
	pwd, _ := json.Marshal(cr.UpdateSecret{OldPassword: newPwdStr.Secret, NewPassword: updatedPwd})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusCreated, string(pwd), okURLJ)

	// login as root and get user info
	cookieStr, _ = app.GenerateToken(defs.RootUserName, am.SuperUserPermission, false, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)
	url = resourcePath + "/" + userName
	data, _ = stRestful.UsersList.GetPropertyAttachedToEntity(userName, propertyName)
	exeCommandCheckRes(t, cr.HTTPGetStr, url, http.StatusOK, "", data.(*am.AmUserInfo))

	// login as user and get user info
	d = data.(*am.AmUserInfo)
	cookieStr, _ = app.GenerateToken(userName, am.UserPermission, d.Pwd.TemporaryPwd, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)
	url = resourcePath + "/" + userName
	exeCommandCheckRes(t, cr.HTTPGetStr, url, http.StatusOK, "", data.(*am.AmUserInfo))
}
func initAListOfUsers(t *testing.T, usersList []string) string {
	cookieStr, _ := app.GenerateToken(defs.RootUserName, am.SuperUserPermission, false, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)

	for _, name := range usersList {
		okURLJ := cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, name)}
		url := resourcePath + "/" + name
		exeCommandCheckRes(t, cr.HTTPPutStr, url, http.StatusCreated, string(uData), okURLJ)
		data, _ := stRestful.UsersList.GetPropertyAttachedToEntity(name, propertyName)
		exeCommandCheckRes(t, cr.HTTPGetStr, url, http.StatusOK, "", data.(*am.AmUserInfo))
	}
	return string(uData)
}
// 1. As a user: Update the password, verify the results
// 2. As a root: Fail to update the password to the root
// 3. As a root: Update the password, verify that it is allowed
func TestUpdatePassword(t *testing.T) {
	userName := usersName[0]

	//	initAListOfUsers(t, usersName)
	cookieStr, _ := app.GenerateToken(userName, am.UserPermission, false, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)

	url := listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserPwdCommand]), usersPath, userName, pwdPath)
	okURLJ := cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, userName)}
	pwd, _ := json.Marshal(cr.UpdateSecret{OldPassword: secretCode, NewPassword: secretCode + "1"})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusCreated, string(pwd), okURLJ)

	url = listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserPwdCommand]), usersPath, defs.RootUserName, pwdPath)
	okURLJ = cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, defs.RootUserName)}
	pwd, _ = json.Marshal(cr.UpdateSecret{OldPassword: rootPwd, NewPassword: secretCode + "2"})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusMethodNotAllowed, string(pwd), cr.Error{Code: http.StatusMethodNotAllowed})

	cookieStr, _ = app.GenerateToken(defs.RootUserName, am.SuperUserPermission, false, clientIP, stRestful.SignKey)
	cr.TestSetCookie(cookieStr)
	url = listener + servicePath + fmt.Sprintf(cr.ConvertCommandToRequest(urlCommands[handleUserPwdCommand]), usersPath, defs.RootUserName, pwdPath)
	okURLJ = cr.URL{URL: fmt.Sprintf("%v/%v", servicePath, defs.RootUserName)}
	pwd, _ = json.Marshal(cr.UpdateSecret{OldPassword: rootPwd, NewPassword: secretCode + "1"})
	exeCommandCheckRes(t, cr.HTTPPatchStr, url, http.StatusCreated, string(pwd), okURLJ)
}