[MM-56653] Improve license loading errors (#26050)

Этот коммит содержится в:
Ben Schumacher
2024-04-05 16:59:19 +02:00
коммит произвёл GitHub
родитель 1a9355b2eb
Коммит 71e26b8df2
6 изменённых файлов: 86 добавлений и 84 удалений

Просмотреть файл

@@ -11,6 +11,7 @@ import (
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"net/http"
"os"
@@ -32,33 +33,32 @@ func init() {
type LicenseValidatorIface interface {
LicenseFromBytes(licenseBytes []byte) (*model.License, *model.AppError)
ValidateLicense(signed []byte) (bool, string)
ValidateLicense(signed []byte) (string, error)
}
type LicenseValidatorImpl struct {
}
func (l *LicenseValidatorImpl) LicenseFromBytes(licenseBytes []byte) (*model.License, *model.AppError) {
success, licenseStr := l.ValidateLicense(licenseBytes)
if !success {
return nil, model.NewAppError("LicenseFromBytes", model.InvalidLicenseError, nil, "", http.StatusBadRequest)
licenseStr, err := l.ValidateLicense(licenseBytes)
if err != nil {
return nil, model.NewAppError("LicenseFromBytes", model.InvalidLicenseError, nil, "", http.StatusBadRequest).Wrap(err)
}
var license model.License
if jsonErr := json.Unmarshal([]byte(licenseStr), &license); jsonErr != nil {
return nil, model.NewAppError("LicenseFromBytes", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr)
if err := json.Unmarshal([]byte(licenseStr), &license); err != nil {
return nil, model.NewAppError("LicenseFromBytes", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
return &license, nil
}
func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) {
func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (string, error) {
decoded := make([]byte, base64.StdEncoding.DecodedLen(len(signed)))
_, err := base64.StdEncoding.Decode(decoded, signed)
if err != nil {
mlog.Error("Encountered error decoding license", mlog.Err(err))
return false, ""
return "", fmt.Errorf("encountered error decoding license: %w", err)
}
// remove null terminator
@@ -67,8 +67,7 @@ func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) {
}
if len(decoded) <= 256 {
mlog.Error("Signed license not long enough")
return false, ""
return "", fmt.Errorf("Signed license not long enough")
}
plaintext := decoded[:len(decoded)-256]
@@ -85,8 +84,7 @@ func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) {
public, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
mlog.Error("Encountered error signing license", mlog.Err(err))
return false, ""
return "", fmt.Errorf("Encountered error signing license: %w", err)
}
rsaPublic := public.(*rsa.PublicKey)
@@ -97,37 +95,34 @@ func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) {
err = rsa.VerifyPKCS1v15(rsaPublic, crypto.SHA512, d, signature)
if err != nil {
mlog.Error("Invalid signature", mlog.Err(err))
return false, ""
return "", fmt.Errorf("Invalid signature: %w", err)
}
return true, string(plaintext)
return string(plaintext), nil
}
func GetAndValidateLicenseFileFromDisk(location string) (*model.License, []byte) {
func GetAndValidateLicenseFileFromDisk(location string) (*model.License, []byte, error) {
fileName := GetLicenseFileLocation(location)
mlog.Info("License key has not been uploaded. Loading license key from disk.", mlog.String("filename", fileName))
if _, err := os.Stat(fileName); err != nil {
mlog.Debug("We could not find the license key in the database or on disk at", mlog.String("filename", fileName))
return nil, nil
return nil, nil, fmt.Errorf("We could not find the license key on disk at %s: %w", fileName, err)
}
mlog.Info("License key has not been uploaded. Loading license key from disk at", mlog.String("filename", fileName))
licenseBytes := GetLicenseFileFromDisk(fileName)
success, licenseStr := LicenseValidator.ValidateLicense(licenseBytes)
if !success {
mlog.Error("Found license key at %v but it appears to be invalid.", mlog.String("filename", fileName))
return nil, nil
licenseStr, err := LicenseValidator.ValidateLicense(licenseBytes)
if err != nil {
return nil, nil, fmt.Errorf("Found license key at %s but it appears to be invalid: %w", fileName, err)
}
var license model.License
if jsonErr := json.Unmarshal([]byte(licenseStr), &license); jsonErr != nil {
mlog.Error("Failed to decode license from JSON", mlog.Err(jsonErr))
return nil, nil
return nil, nil, fmt.Errorf("Found license key at %s but it appears to be invalid: %w", fileName, err)
}
return &license, licenseBytes
return &license, licenseBytes, nil
}
func GetLicenseFileFromDisk(fileName string) []byte {

Просмотреть файл

@@ -19,12 +19,12 @@ var validTestLicense = []byte("eyJpZCI6InpvZ3c2NW44Z2lmajVkbHJoYThtYnUxcGl3Iiwia
func TestValidateLicense(t *testing.T) {
t.Run("should fail with junk data", func(t *testing.T) {
b1 := []byte("junk")
ok, _ := LicenseValidator.ValidateLicense(b1)
require.False(t, ok, "should have failed - bad license")
_, err := LicenseValidator.ValidateLicense(b1)
require.Error(t, err, "should have failed - bad license")
b2 := []byte("junkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunk")
ok, _ = LicenseValidator.ValidateLicense(b2)
require.False(t, ok, "should have failed - bad license")
_, err = LicenseValidator.ValidateLicense(b2)
require.Error(t, err, "should have failed - bad license")
})
t.Run("should not panic on shorter than expected input", func(t *testing.T) {
@@ -42,8 +42,8 @@ func TestValidateLicense(t *testing.T) {
err = encoder.Close()
require.NoError(t, err)
ok, str := LicenseValidator.ValidateLicense(licenseData.Bytes())
require.False(t, ok)
str, err := LicenseValidator.ValidateLicense(licenseData.Bytes())
require.Error(t, err)
require.Empty(t, str)
})
@@ -61,8 +61,8 @@ func TestValidateLicense(t *testing.T) {
err = encoder.Close()
require.NoError(t, err)
ok, str := LicenseValidator.ValidateLicense(licenseData.Bytes())
require.False(t, ok)
str, err := LicenseValidator.ValidateLicense(licenseData.Bytes())
require.Error(t, err)
require.Empty(t, str)
})
@@ -70,8 +70,8 @@ func TestValidateLicense(t *testing.T) {
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest)
defer os.Unsetenv("MM_SERVICEENVIRONMENT")
ok, str := LicenseValidator.ValidateLicense(nil)
require.False(t, ok)
str, err := LicenseValidator.ValidateLicense(nil)
require.Error(t, err)
require.Empty(t, str)
})
@@ -79,8 +79,8 @@ func TestValidateLicense(t *testing.T) {
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest)
defer os.Unsetenv("MM_SERVICEENVIRONMENT")
ok, str := LicenseValidator.ValidateLicense(validTestLicense)
require.True(t, ok)
str, err := LicenseValidator.ValidateLicense(validTestLicense)
require.NoError(t, err)
require.NotEmpty(t, str)
})
@@ -88,8 +88,8 @@ func TestValidateLicense(t *testing.T) {
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentProduction)
defer os.Unsetenv("MM_SERVICEENVIRONMENT")
ok, str := LicenseValidator.ValidateLicense(validTestLicense)
require.False(t, ok)
str, err := LicenseValidator.ValidateLicense(validTestLicense)
require.Error(t, err)
require.Empty(t, str)
})
}
@@ -117,7 +117,7 @@ func TestGetLicenseFileFromDisk(t *testing.T) {
fileBytes := GetLicenseFileFromDisk(f.Name())
require.NotEmpty(t, fileBytes, "should have read the file")
success, _ := LicenseValidator.ValidateLicense(fileBytes)
assert.False(t, success, "should have been an invalid file")
_, err = LicenseValidator.ValidateLicense(fileBytes)
assert.Error(t, err, "should have been an invalid file")
})
}

Просмотреть файл

@@ -43,24 +43,24 @@ func (_m *LicenseValidatorIface) LicenseFromBytes(licenseBytes []byte) (*model.L
}
// ValidateLicense provides a mock function with given fields: signed
func (_m *LicenseValidatorIface) ValidateLicense(signed []byte) (bool, string) {
func (_m *LicenseValidatorIface) ValidateLicense(signed []byte) (string, error) {
ret := _m.Called(signed)
var r0 bool
var r1 string
if rf, ok := ret.Get(0).(func([]byte) (bool, string)); ok {
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func([]byte) (string, error)); ok {
return rf(signed)
}
if rf, ok := ret.Get(0).(func([]byte) bool); ok {
if rf, ok := ret.Get(0).(func([]byte) string); ok {
r0 = rf(signed)
} else {
r0 = ret.Get(0).(bool)
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func([]byte) string); ok {
if rf, ok := ret.Get(1).(func([]byte) error); ok {
r1 = rf(signed)
} else {
r1 = ret.Get(1).(string)
r1 = ret.Error(1)
}
return r0, r1