func Test_UseOfTemporaryPwd(t *testing.T) {
	user, err := NewUserPwd(defaultPassword, defaultSaltStr, true)
	if err != nil {
		t.Error("Test fail, can't initialized user password structure, error:", err)
		t.FailNow()
	}
	tPwd, _ := salt.GenerateSaltedPassword(defaultPassword, MinPasswordLength, MaxPasswordLength, user.Salt, -1)
	pwd := GetHashedPwd(tPwd)
	user.SetTemporaryPwd(true)
	err = user.IsPasswordMatch(pwd)
	if err != nil {
		t.Errorf("Test fail: password '%v' was not accepted but it is the same as the current password, %v, current time: %v, error: %v", pwd, user, time.Now(), err)
	}
	err = user.IsPasswordMatch(pwd)
	if err == nil {
		t.Errorf("Test fail: password '%v' accepted but it was a temporary password, and it was already used, %v, current time: %v", pwd, user, time.Now())
	}
}
Check that temporary password can be used exctly once
package password
import (
	"crypto/rand"
	"fmt"
	"io"
	"testing"
	"time"
	defs "github.com/ibm-security-innovation/libsecurity-go/defs"
	"github.com/ibm-security-innovation/libsecurity-go/salt"
)
var (
	defaultPassword []byte
	defaultSaltStr  = []byte("abcd")
)
func init() {
	defaultPassword = []byte(GenerateNewValidPassword())
}
func checkValidPasswordLen(t *testing.T, user *UserPwd) {
	pwd := ""
	for i := 0; i < MaxPasswordLength+2; i++ {
		err := isPwdLengthValid([]byte(pwd))
		if err != nil && i >= MinPasswordLength && i <= MaxPasswordLength {
			t.Errorf("Test fail: Legal password:'%v', length: %v, was not excepted, error: %v", pwd, len(pwd), err)
		}
		if err == nil && (i < MinPasswordLength || i > MaxPasswordLength) {
			t.Errorf("Test fail: Legal password: '%v', length: %v, was not excepted", pwd, len(pwd))
		}
		pwd += "a"
	}
}
func checkUnusabledOldPasswords(t *testing.T, user *UserPwd) {
	unused := 1
	for i := 0; i < defaultNumberOfOldPasswords-unused; i++ {
		user.OldPasswords[i] = GetHashedPwd([]byte(string(defaultPassword) + fmt.Sprintf("%d", i)))
	}
	buf := make([]byte, 1)
	for i := 0; i < defaultNumberOfOldPasswords*4; i++ {
		_, err := io.ReadFull(rand.Reader, buf)
		if err != nil {
			panic(fmt.Errorf("random read failed: %v", err))
		}
		idx := int(buf[0]) % (defaultNumberOfOldPasswords * 2)
		pwd := []byte(string(defaultPassword) + fmt.Sprintf("%d", idx))
		err = user.IsNewPwdValid(pwd, false)
		if err == nil && idx < defaultNumberOfOldPasswords-unused {
			t.Errorf("Test fail: password '%v' was already used, but it was accepted, user data: %v", pwd, user)
			t.FailNow()
		} else if err != nil && idx >= defaultNumberOfOldPasswords-unused {
			t.Errorf("Test fail: user: %v, password '%v' rejected, but it was't used, error: %v", user, pwd, err)
			t.FailNow()
		}
	}
}
func Test_ValidPwd(t *testing.T) {
	user, err := NewUserPwd(defaultPassword, defaultSaltStr, true)
	if err != nil {
		t.Error("Test fail, can't initialized user password structure, error:", err)
		t.FailNow()
	}
	checkValidPasswordLen(t, user)
	checkUnusabledOldPasswords(t, user)
}
func Test_UpdatePwd(t *testing.T) {
	user, err := NewUserPwd(defaultPassword, defaultSaltStr, true)
	if err != nil {
		t.Error("Test fail, can't initialized user password structure, error:", err)
		t.FailNow()
	}
	for i := 0; i < defaultNumberOfOldPasswords*2; i++ {
		pwd := []byte(string(defaultPassword) + fmt.Sprintf("%d", i))
		newPwd, err := user.UpdatePassword(user.Password, pwd, true)
		if err != nil {
			t.Errorf("Test fail: user: %v, password %v, ('%v') rejected, but it was't used, error: %v", user, newPwd, string(pwd), err)
		}
		for j := i; j >= i-defaultNumberOfOldPasswords && j >= 0; j-- {
			pwd := []byte(string(defaultPassword) + fmt.Sprintf("%d", j))
			newPwd, err := user.UpdatePassword(user.Password, pwd, true)
			if err == nil {
				t.Errorf("Test fail: password %v ('%v') was already used, but it was accepted, user data: %v", newPwd, string(pwd), user)
			}
		}
	}
}
func Test_VerifyPwd(t *testing.T) {
	uPwd, err := NewUserPwd(defaultPassword, defaultSaltStr, true)
	if err != nil {
		t.Error("Test fail, can't initialized user password structure, error:", err)
		t.FailNow()
	}
	tPwd, _ := salt.GenerateSaltedPassword(defaultPassword, MinPasswordLength, MaxPasswordLength, uPwd.Salt, -1)
	pwd := GetHashedPwd(tPwd)
	err = uPwd.IsPasswordMatch(pwd)
	if err != nil {
		t.Errorf("Test fail: password '%v' was not accepted but it is the same as the current password, %v, error: %v", pwd, uPwd, err)
	}
	tPwd, _ = salt.GenerateSaltedPassword([]byte(string(pwd)+"a"), MinPasswordLength, MaxPasswordLength, uPwd.Salt, -1)
	wrongPwd := GetHashedPwd(tPwd)
	err = uPwd.IsPasswordMatch(wrongPwd)
	if err == nil {
		t.Errorf("Test fail: password '%v' was approved but it is different from the current password, %v", wrongPwd, uPwd)
	}
	for i := -2; i < 3; i++ {
		if i == 0 {
			continue
		}
		uPwd.Expiration = time.Now().Add(time.Duration(i) * time.Second)
		err = uPwd.IsPasswordMatch(pwd)
		if err == nil && i <= 0 {
			t.Errorf("Test fail: password was approved but it is not valid (expired, time now %v), %v", time.Now(), uPwd.Expiration)
		} else if err != nil && i > 0 {
			t.Errorf("Test fail: password was not approved but it valid (time now %v), %v", time.Now(), uPwd.Expiration)
		}
	}
}