Move license storage to database
Этот коммит содержится в:
@@ -81,9 +81,24 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writeFileLocally(data, utils.LicenseLocation()); err != nil {
|
record := &model.LicenseRecord{}
|
||||||
c.LogAudit("failed - could not save license file")
|
record.Id = license.Id
|
||||||
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.save.app_error", nil, "path="+utils.LicenseLocation())
|
record.Bytes = string(data)
|
||||||
|
rchan := Srv.Store.License().Save(record)
|
||||||
|
|
||||||
|
sysVar := &model.System{}
|
||||||
|
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
|
||||||
|
sysVar.Value = license.Id
|
||||||
|
schan := Srv.Store.System().SaveOrUpdate(sysVar)
|
||||||
|
|
||||||
|
if result := <-rchan; result.Err != nil {
|
||||||
|
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.save.app_error", nil, "err="+result.Err.Error())
|
||||||
|
utils.RemoveLicense()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if result := <-schan; result.Err != nil {
|
||||||
|
c.Err = model.NewLocAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "")
|
||||||
utils.RemoveLicense()
|
utils.RemoveLicense()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -100,9 +115,14 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
c.LogAudit("")
|
c.LogAudit("")
|
||||||
|
|
||||||
if ok := utils.RemoveLicense(); !ok {
|
utils.RemoveLicense()
|
||||||
c.LogAudit("failed - could not remove license file")
|
|
||||||
c.Err = model.NewLocAppError("removeLicense", "api.license.remove_license.remove.app_error", nil, "")
|
sysVar := &model.System{}
|
||||||
|
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
|
||||||
|
sysVar.Value = ""
|
||||||
|
|
||||||
|
if result := <-Srv.Store.System().Update(sysVar); result.Err != nil {
|
||||||
|
c.Err = model.NewLocAppError("removeLicense", "api.license.remove_license.update.app_error", nil, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
i18n/en.json
26
i18n/en.json
@@ -611,6 +611,10 @@
|
|||||||
"id": "api.license.add_license.save.app_error",
|
"id": "api.license.add_license.save.app_error",
|
||||||
"translation": "License did not save properly."
|
"translation": "License did not save properly."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.license.add_license.save_active.app_error",
|
||||||
|
"translation": "Active license ID did not save properly."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.license.add_license.unique_users.app_error",
|
"id": "api.license.add_license.unique_users.app_error",
|
||||||
"translation": "This license only supports {{.Users}} users, when your system has {{.Count}} unique users. Unique users are counted distinctly by email address. You can see total user count under Site Reports -> View Statistics."
|
"translation": "This license only supports {{.Users}} users, when your system has {{.Count}} unique users. Unique users are counted distinctly by email address. You can see total user count under Site Reports -> View Statistics."
|
||||||
@@ -1731,6 +1735,10 @@
|
|||||||
"id": "manaultesting.test_autolink.unable.app_error",
|
"id": "manaultesting.test_autolink.unable.app_error",
|
||||||
"translation": "Unable to get channels"
|
"translation": "Unable to get channels"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "mattermost.load_license.find.warn",
|
||||||
|
"translation": "Unable to find active license"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "mattermost.bulletin.subject",
|
"id": "mattermost.bulletin.subject",
|
||||||
"translation": "Mattermost Security Bulletin"
|
"translation": "Mattermost Security Bulletin"
|
||||||
@@ -2915,6 +2923,18 @@
|
|||||||
"id": "store.sql_system.update.app_error",
|
"id": "store.sql_system.update.app_error",
|
||||||
"translation": "We encountered an error updating the system property"
|
"translation": "We encountered an error updating the system property"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_license.save.app_error",
|
||||||
|
"translation": "We encountered an error saving the license"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_license.get.app_error",
|
||||||
|
"translation": "We encountered an error getting the license"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_license.get.missing.app_error",
|
||||||
|
"translation": "A license with that ID was not found"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "store.sql_team.get.find.app_error",
|
"id": "store.sql_team.get.find.app_error",
|
||||||
"translation": "We couldn't find the existing team"
|
"translation": "We couldn't find the existing team"
|
||||||
@@ -3203,10 +3223,6 @@
|
|||||||
"id": "utils.license.load_license.invalid.warn",
|
"id": "utils.license.load_license.invalid.warn",
|
||||||
"translation": "No valid enterprise license found"
|
"translation": "No valid enterprise license found"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "utils.license.load_license.open_find.warn",
|
|
||||||
"translation": "Unable to open/find license file"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "utils.license.remove_license.unable.error",
|
"id": "utils.license.remove_license.unable.error",
|
||||||
"translation": "Unable to remove license file, err=%v"
|
"translation": "Unable to remove license file, err=%v"
|
||||||
@@ -3531,4 +3547,4 @@
|
|||||||
"id": "web.watcher_fail.error",
|
"id": "web.watcher_fail.error",
|
||||||
"translation": "Failed to add directory to watcher %v"
|
"translation": "Failed to add directory to watcher %v"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3203,10 +3203,6 @@
|
|||||||
"id": "utils.license.load_license.invalid.warn",
|
"id": "utils.license.load_license.invalid.warn",
|
||||||
"translation": "No se encontró una licencia enterprise válida"
|
"translation": "No se encontró una licencia enterprise válida"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "utils.license.load_license.open_find.warn",
|
|
||||||
"translation": "No pudimos encontrar/abrir el achivo de licencia"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "utils.license.remove_license.unable.error",
|
"id": "utils.license.remove_license.unable.error",
|
||||||
"translation": "No se pudo remover el archivo de la licencia, err=%v"
|
"translation": "No se pudo remover el archivo de la licencia, err=%v"
|
||||||
@@ -3531,4 +3527,4 @@
|
|||||||
"id": "web.watcher_fail.error",
|
"id": "web.watcher_fail.error",
|
||||||
"translation": "Falla al agregar el directorio a ser vigilado %v"
|
"translation": "Falla al agregar el directorio a ser vigilado %v"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ func main() {
|
|||||||
web.InitWeb()
|
web.InitWeb()
|
||||||
|
|
||||||
if model.BuildEnterpriseReady == "true" {
|
if model.BuildEnterpriseReady == "true" {
|
||||||
utils.LoadLicense()
|
loadLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagRunCmds {
|
if flagRunCmds {
|
||||||
@@ -95,6 +95,26 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadLicense() {
|
||||||
|
licenseId := ""
|
||||||
|
if result := <-api.Srv.Store.System().Get(); result.Err == nil {
|
||||||
|
props := result.Data.(model.StringMap)
|
||||||
|
licenseId = props[model.SYSTEM_ACTIVE_LICENSE_ID]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(licenseId) != 26 {
|
||||||
|
l4g.Warn(utils.T("mattermost.load_license.find.warn"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if result := <-api.Srv.Store.License().Get(licenseId); result.Err == nil {
|
||||||
|
record := result.Data.(*model.LicenseRecord)
|
||||||
|
utils.LoadLicense([]byte(record.Bytes))
|
||||||
|
} else {
|
||||||
|
l4g.Warn(utils.T("mattermost.load_license.find.warn"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setDiagnosticId() {
|
func setDiagnosticId() {
|
||||||
if result := <-api.Srv.Store.System().Get(); result.Err == nil {
|
if result := <-api.Srv.Store.System().Get(); result.Err == nil {
|
||||||
props := result.Data.(model.StringMap)
|
props := result.Data.(model.StringMap)
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type LicenseRecord struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
CreateAt int64 `json:"create_at"`
|
||||||
|
Bytes string `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
type License struct {
|
type License struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
IssuedAt int64 `json:"issued_at"`
|
IssuedAt int64 `json:"issued_at"`
|
||||||
@@ -83,3 +89,23 @@ func LicenseFromJson(data io.Reader) *License {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lr *LicenseRecord) IsValid() *AppError {
|
||||||
|
if len(lr.Id) != 26 {
|
||||||
|
return NewLocAppError("LicenseRecord.IsValid", "model.license_record.is_valid.id.app_error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if lr.CreateAt == 0 {
|
||||||
|
return NewLocAppError("LicenseRecord.IsValid", "model.license_record.is_valid.create_at.app_error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lr.Bytes) == 0 || len(lr.Bytes) > 10000 {
|
||||||
|
return NewLocAppError("LicenseRecord.IsValid", "model.license_record.is_valid.create_at.app_error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lr *LicenseRecord) PreSave() {
|
||||||
|
lr.CreateAt = GetMillis()
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const (
|
|||||||
SYSTEM_DIAGNOSTIC_ID = "DiagnosticId"
|
SYSTEM_DIAGNOSTIC_ID = "DiagnosticId"
|
||||||
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
|
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
|
||||||
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
|
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
|
||||||
|
SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId"
|
||||||
)
|
)
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
|
|||||||
83
store/sql_license_store.go
Обычный файл
83
store/sql_license_store.go
Обычный файл
@@ -0,0 +1,83 @@
|
|||||||
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/platform/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SqlLicenseStore struct {
|
||||||
|
*SqlStore
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSqlLicenseStore(sqlStore *SqlStore) LicenseStore {
|
||||||
|
ls := &SqlLicenseStore{sqlStore}
|
||||||
|
|
||||||
|
for _, db := range sqlStore.GetAllConns() {
|
||||||
|
table := db.AddTableWithName(model.LicenseRecord{}, "Licenses").SetKeys(false, "Id")
|
||||||
|
table.ColMap("Id").SetMaxSize(26)
|
||||||
|
table.ColMap("Bytes").SetMaxSize(10000)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ls
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls SqlLicenseStore) UpgradeSchemaIfNeeded() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls SqlLicenseStore) CreateIndexesIfNotExists() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls SqlLicenseStore) Save(license *model.LicenseRecord) StoreChannel {
|
||||||
|
|
||||||
|
storeChannel := make(StoreChannel)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
result := StoreResult{}
|
||||||
|
|
||||||
|
license.PreSave()
|
||||||
|
if result.Err = license.IsValid(); result.Err != nil {
|
||||||
|
storeChannel <- result
|
||||||
|
close(storeChannel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only insert if not exists
|
||||||
|
if err := ls.GetReplica().SelectOne(&model.LicenseRecord{}, "SELECT * FROM Licenses WHERE Id = :Id", map[string]interface{}{"Id": license.Id}); err != nil {
|
||||||
|
if err := ls.GetMaster().Insert(license); err != nil {
|
||||||
|
result.Err = model.NewLocAppError("SqlLicenseStore.Save", "store.sql_license.save.app_error", nil, "license_id="+license.Id+", "+err.Error())
|
||||||
|
} else {
|
||||||
|
result.Data = license
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storeChannel <- result
|
||||||
|
close(storeChannel)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return storeChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls SqlLicenseStore) Get(id string) StoreChannel {
|
||||||
|
|
||||||
|
storeChannel := make(StoreChannel)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
result := StoreResult{}
|
||||||
|
|
||||||
|
if obj, err := ls.GetReplica().Get(model.LicenseRecord{}, id); err != nil {
|
||||||
|
result.Err = model.NewLocAppError("SqlLicenseStore.Get", "store.sql_license.get.app_error", nil, "license_id="+id+", "+err.Error())
|
||||||
|
} else if obj == nil {
|
||||||
|
result.Err = model.NewLocAppError("SqlLicenseStore.Get", "store.sql_license.get.missing.app_error", nil, "license_id="+id)
|
||||||
|
} else {
|
||||||
|
result.Data = obj.(*model.LicenseRecord)
|
||||||
|
}
|
||||||
|
|
||||||
|
storeChannel <- result
|
||||||
|
close(storeChannel)
|
||||||
|
|
||||||
|
}()
|
||||||
|
|
||||||
|
return storeChannel
|
||||||
|
}
|
||||||
43
store/sql_license_store_test.go
Обычный файл
43
store/sql_license_store_test.go
Обычный файл
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/platform/model"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLicenseStoreSave(t *testing.T) {
|
||||||
|
Setup()
|
||||||
|
|
||||||
|
l1 := model.LicenseRecord{}
|
||||||
|
l1.Id = model.NewId()
|
||||||
|
l1.Bytes = "junk"
|
||||||
|
|
||||||
|
if err := (<-store.License().Save(&l1)).Err; err != nil {
|
||||||
|
t.Fatal("couldn't save license record", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := (<-store.License().Save(&l1)).Err; err != nil {
|
||||||
|
t.Fatal("shouldn't fail on trying to save existing license record", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLicenseStoreGet(t *testing.T) {
|
||||||
|
Setup()
|
||||||
|
|
||||||
|
l1 := model.LicenseRecord{}
|
||||||
|
l1.Id = model.NewId()
|
||||||
|
l1.Bytes = "junk"
|
||||||
|
|
||||||
|
Must(store.License().Save(&l1))
|
||||||
|
|
||||||
|
if r := <-store.License().Get(l1.Id); r.Err != nil {
|
||||||
|
t.Fatal("couldn't get license", r.Err)
|
||||||
|
} else {
|
||||||
|
if r.Data.(*model.LicenseRecord).Bytes != l1.Bytes {
|
||||||
|
t.Fatal("license bytes didn't match")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,6 +49,7 @@ type SqlStore struct {
|
|||||||
webhook WebhookStore
|
webhook WebhookStore
|
||||||
command CommandStore
|
command CommandStore
|
||||||
preference PreferenceStore
|
preference PreferenceStore
|
||||||
|
license LicenseStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSqlStore() Store {
|
func NewSqlStore() Store {
|
||||||
@@ -103,6 +104,7 @@ func NewSqlStore() Store {
|
|||||||
sqlStore.webhook = NewSqlWebhookStore(sqlStore)
|
sqlStore.webhook = NewSqlWebhookStore(sqlStore)
|
||||||
sqlStore.command = NewSqlCommandStore(sqlStore)
|
sqlStore.command = NewSqlCommandStore(sqlStore)
|
||||||
sqlStore.preference = NewSqlPreferenceStore(sqlStore)
|
sqlStore.preference = NewSqlPreferenceStore(sqlStore)
|
||||||
|
sqlStore.license = NewSqlLicenseStore(sqlStore)
|
||||||
|
|
||||||
err := sqlStore.master.CreateTablesIfNotExists()
|
err := sqlStore.master.CreateTablesIfNotExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -120,6 +122,7 @@ func NewSqlStore() Store {
|
|||||||
sqlStore.webhook.(*SqlWebhookStore).UpgradeSchemaIfNeeded()
|
sqlStore.webhook.(*SqlWebhookStore).UpgradeSchemaIfNeeded()
|
||||||
sqlStore.command.(*SqlCommandStore).UpgradeSchemaIfNeeded()
|
sqlStore.command.(*SqlCommandStore).UpgradeSchemaIfNeeded()
|
||||||
sqlStore.preference.(*SqlPreferenceStore).UpgradeSchemaIfNeeded()
|
sqlStore.preference.(*SqlPreferenceStore).UpgradeSchemaIfNeeded()
|
||||||
|
sqlStore.license.(*SqlLicenseStore).UpgradeSchemaIfNeeded()
|
||||||
|
|
||||||
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
|
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
|
||||||
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
|
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
|
||||||
@@ -132,6 +135,7 @@ func NewSqlStore() Store {
|
|||||||
sqlStore.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists()
|
sqlStore.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists()
|
||||||
sqlStore.command.(*SqlCommandStore).CreateIndexesIfNotExists()
|
sqlStore.command.(*SqlCommandStore).CreateIndexesIfNotExists()
|
||||||
sqlStore.preference.(*SqlPreferenceStore).CreateIndexesIfNotExists()
|
sqlStore.preference.(*SqlPreferenceStore).CreateIndexesIfNotExists()
|
||||||
|
sqlStore.license.(*SqlLicenseStore).CreateIndexesIfNotExists()
|
||||||
|
|
||||||
sqlStore.preference.(*SqlPreferenceStore).DeleteUnusedFeatures()
|
sqlStore.preference.(*SqlPreferenceStore).DeleteUnusedFeatures()
|
||||||
|
|
||||||
@@ -523,6 +527,10 @@ func (ss SqlStore) Preference() PreferenceStore {
|
|||||||
return ss.preference
|
return ss.preference
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss SqlStore) License() LicenseStore {
|
||||||
|
return ss.license
|
||||||
|
}
|
||||||
|
|
||||||
type mattermConverter struct{}
|
type mattermConverter struct{}
|
||||||
|
|
||||||
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {
|
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
package store
|
package store
|
||||||
@@ -47,6 +47,30 @@ func (s SqlSystemStore) Save(system *model.System) StoreChannel {
|
|||||||
return storeChannel
|
return storeChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s SqlSystemStore) SaveOrUpdate(system *model.System) StoreChannel {
|
||||||
|
|
||||||
|
storeChannel := make(StoreChannel)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
result := StoreResult{}
|
||||||
|
|
||||||
|
if err := s.GetReplica().SelectOne(&model.System{}, "SELECT * FROM Systems WHERE Name = :Name", map[string]interface{}{"Name": system.Name}); err == nil {
|
||||||
|
if _, err := s.GetMaster().Update(system); err != nil {
|
||||||
|
result.Err = model.NewLocAppError("SqlSystemStore.SaveOrUpdate", "store.sql_system.update.app_error", nil, "")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := s.GetMaster().Insert(system); err != nil {
|
||||||
|
result.Err = model.NewLocAppError("SqlSystemStore.SaveOrUpdate", "store.sql_system.save.app_error", nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storeChannel <- result
|
||||||
|
close(storeChannel)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return storeChannel
|
||||||
|
}
|
||||||
|
|
||||||
func (s SqlSystemStore) Update(system *model.System) StoreChannel {
|
func (s SqlSystemStore) Update(system *model.System) StoreChannel {
|
||||||
|
|
||||||
storeChannel := make(StoreChannel)
|
storeChannel := make(StoreChannel)
|
||||||
|
|||||||
@@ -31,3 +31,19 @@ func TestSqlSystemStore(t *testing.T) {
|
|||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSqlSystemStoreSaveOrUpdate(t *testing.T) {
|
||||||
|
Setup()
|
||||||
|
|
||||||
|
system := &model.System{Name: model.NewId(), Value: "value"}
|
||||||
|
|
||||||
|
if err := (<-store.System().SaveOrUpdate(system)).Err; err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
system.Value = "value2"
|
||||||
|
|
||||||
|
if r := <-store.System().SaveOrUpdate(system); r.Err != nil {
|
||||||
|
t.Fatal(r.Err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
package store
|
package store
|
||||||
@@ -39,6 +39,7 @@ type Store interface {
|
|||||||
Webhook() WebhookStore
|
Webhook() WebhookStore
|
||||||
Command() CommandStore
|
Command() CommandStore
|
||||||
Preference() PreferenceStore
|
Preference() PreferenceStore
|
||||||
|
License() LicenseStore
|
||||||
MarkSystemRanUnitTests()
|
MarkSystemRanUnitTests()
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
@@ -164,6 +165,7 @@ type OAuthStore interface {
|
|||||||
|
|
||||||
type SystemStore interface {
|
type SystemStore interface {
|
||||||
Save(system *model.System) StoreChannel
|
Save(system *model.System) StoreChannel
|
||||||
|
SaveOrUpdate(system *model.System) StoreChannel
|
||||||
Update(system *model.System) StoreChannel
|
Update(system *model.System) StoreChannel
|
||||||
Get() StoreChannel
|
Get() StoreChannel
|
||||||
}
|
}
|
||||||
@@ -203,3 +205,8 @@ type PreferenceStore interface {
|
|||||||
PermanentDeleteByUser(userId string) StoreChannel
|
PermanentDeleteByUser(userId string) StoreChannel
|
||||||
IsFeatureEnabled(feature, userId string) StoreChannel
|
IsFeatureEnabled(feature, userId string) StoreChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LicenseStore interface {
|
||||||
|
Save(license *model.LicenseRecord) StoreChannel
|
||||||
|
Get(id string) StoreChannel
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -22,10 +18,6 @@ import (
|
|||||||
"github.com/mattermost/platform/model"
|
"github.com/mattermost/platform/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
LICENSE_FILENAME = "active.dat"
|
|
||||||
)
|
|
||||||
|
|
||||||
var IsLicensed bool = false
|
var IsLicensed bool = false
|
||||||
var License *model.License = &model.License{}
|
var License *model.License = &model.License{}
|
||||||
var ClientLicense map[string]string = make(map[string]string)
|
var ClientLicense map[string]string = make(map[string]string)
|
||||||
@@ -41,18 +33,8 @@ NxpC+5KFhU+xSeeklNqwCgnlOyZ7qSTxmdJHb+60SwuYnnGIYzLJhY4LYDr4J+KR
|
|||||||
1wIDAQAB
|
1wIDAQAB
|
||||||
-----END PUBLIC KEY-----`)
|
-----END PUBLIC KEY-----`)
|
||||||
|
|
||||||
func LoadLicense() {
|
func LoadLicense(licenseBytes []byte) {
|
||||||
file, err := os.Open(LicenseLocation())
|
if success, licenseStr := ValidateLicense(licenseBytes); success {
|
||||||
if err != nil {
|
|
||||||
l4g.Warn(T("utils.license.load_license.open_find.warn"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
io.Copy(buf, file)
|
|
||||||
|
|
||||||
if success, licenseStr := ValidateLicense(buf.Bytes()); success {
|
|
||||||
license := model.LicenseFromJson(strings.NewReader(licenseStr))
|
license := model.LicenseFromJson(strings.NewReader(licenseStr))
|
||||||
SetLicense(license)
|
SetLicense(license)
|
||||||
return
|
return
|
||||||
@@ -74,21 +56,10 @@ func SetLicense(license *model.License) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func LicenseLocation() string {
|
func RemoveLicense() {
|
||||||
return filepath.Dir(CfgFileName) + "/" + LICENSE_FILENAME
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveLicense() bool {
|
|
||||||
License = &model.License{}
|
License = &model.License{}
|
||||||
IsLicensed = false
|
IsLicensed = false
|
||||||
ClientLicense = getClientLicense(License)
|
ClientLicense = getClientLicense(License)
|
||||||
|
|
||||||
if err := os.Remove(LicenseLocation()); err != nil {
|
|
||||||
l4g.Error(T("utils.license.remove_license.unable.error"), err.Error())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateLicense(signed []byte) (bool, string) {
|
func ValidateLicense(signed []byte) (bool, string) {
|
||||||
|
|||||||
@@ -454,6 +454,7 @@ export default class AdminSidebar extends React.Component {
|
|||||||
</ul>
|
</ul>
|
||||||
<ul className='nav nav__sub-menu padded'>
|
<ul className='nav nav__sub-menu padded'>
|
||||||
{licenseSettings}
|
{licenseSettings}
|
||||||
|
{audits}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='#'
|
||||||
@@ -466,7 +467,6 @@ export default class AdminSidebar extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{audits}
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user