1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-24 15:49:44 +02:00

Merge pull request #76 from documize/db-support

support for persona 5.7+ and prep'ed support for MariaDB 10.2+
This commit is contained in:
Harvey Kandola 2017-01-18 10:27:47 -08:00 committed by GitHub
commit 73073efd9e
13 changed files with 768 additions and 682 deletions

1
.gitignore vendored
View file

@ -62,3 +62,4 @@ debug
Dockerfile
container.sh
make.sh
jsconfig.json

View file

@ -0,0 +1,14 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
import Ember from 'ember';
export default Ember.Controller.extend({});

View file

@ -15,7 +15,7 @@ import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-rout
export default Ember.Route.extend(AuthenticatedRouteMixin, {
folderService: Ember.inject.service('folder'),
model: function () {
model() {
return this.get('folderService').getAll();
}
});

View file

@ -35,4 +35,4 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
controller.set('model', model);
controller.set("folder", this.get('folderService.currentFolder'));
}
});
});

View file

@ -39,9 +39,10 @@ export default Ember.Route.extend(ApplicationRouteMixin, TooltipMixin, {
this.destroyTooltips();
},
error(error /*, transition*/ ) {
error(error, transition) {
if (error) {
console.log(error);
console.log(transition);
if (netUtil.isAjaxAccessError(error)) {
localStorage.clear();

View file

@ -70,7 +70,7 @@ func Authenticate(w http.ResponseWriter, r *http.Request) {
domain = request.CheckDomain(domain) // TODO optimize by removing this once js allows empty domains
email := strings.TrimSpace(strings.ToLower(credentials[1]))
password := credentials[2]
log.Info("logon attempt for " + domain + " @ " + email)
log.Info("logon attempt " + email + " @ " + domain)
user, err := p.GetUserByDomain(domain, email)
@ -167,8 +167,10 @@ func Authorize(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
}
domain := request.GetSubdomainFromHost(r)
domain2 := request.GetRequestSubdomain(r)
if org.Domain != domain && org.Domain != domain2 {
log.Info(fmt.Sprintf("domain mismatch %s vs. %s vs. %s", domain, domain2, org.Domain))
if org.Domain != domain {
writeUnauthorizedError(w)
return
}

View file

@ -32,7 +32,7 @@ func (p *Persister) AddDocument(document entity.Document) (err error) {
document.Layout = "doc"
}
stmt, err := p.Context.Transaction.Preparex("INSERT INTO document (refId, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
stmt, err := p.Context.Transaction.Preparex("INSERT INTO document (refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
defer utility.Close(stmt)
if err != nil {

View file

@ -16,7 +16,17 @@ import (
"strings"
)
// find the subdomain (which is actually the organisation )
// GetRequestSubdomain extracts subdomain from referring URL.
func GetRequestSubdomain(r *http.Request) string {
return urlSubdomain(r.Referer())
}
// GetSubdomainFromHost extracts the subdomain from the requesting URL.
func GetSubdomainFromHost(r *http.Request) string {
return urlSubdomain(r.Host)
}
// Find the subdomain (which is actually the organisation).
func urlSubdomain(url string) string {
url = strings.ToLower(url)
url = strings.Replace(url, "https://", "", 1)
@ -32,13 +42,3 @@ func urlSubdomain(url string) string {
return CheckDomain(url)
}
// GetRequestSubdomain extracts subdomain from referring URL.
func GetRequestSubdomain(r *http.Request) string {
return urlSubdomain(r.Referer())
}
// GetSubdomainFromHost extracts the subdomain from the requesting URL.
func GetSubdomainFromHost(r *http.Request) string {
return urlSubdomain(r.Host)
}

View file

@ -23,6 +23,11 @@ import (
"github.com/jmoiron/sqlx"
)
// sql variantsa
const sqlVariantMySQL string = "MySQL"
const sqlVariantPercona string = "Percona"
const sqlVariantMariaDB string = "MariaDB"
var dbCheckOK bool // default false
// dbPtr is a pointer to the central connection to the database, used by all database requests.
@ -40,7 +45,7 @@ func Check(Db *sqlx.DB, connectionString string) bool {
web.SiteInfo.DBname = strings.Split(csBits[len(csBits)-1], "?")[0]
}
rows, err := Db.Query("SELECT VERSION() AS version, @@character_set_database AS charset, @@collation_database AS collation;")
rows, err := Db.Query("SELECT VERSION() AS version, @@version_comment as comment, @@character_set_database AS charset, @@collation_database AS collation;")
if err != nil {
log.Error("Can't get MySQL configuration", err)
web.SiteInfo.Issue = "Can't get MySQL configuration: " + err.Error()
@ -48,13 +53,15 @@ func Check(Db *sqlx.DB, connectionString string) bool {
return false
}
defer utility.Close(rows)
var version, charset, collation string
var version, dbComment, charset, collation string
if rows.Next() {
err = rows.Scan(&version, &charset, &collation)
err = rows.Scan(&version, &dbComment, &charset, &collation)
}
if err == nil {
err = rows.Err() // get any error encountered during iteration
}
if err != nil {
log.Error("no MySQL configuration returned", err)
web.SiteInfo.Issue = "no MySQL configuration return issue: " + err.Error()
@ -62,34 +69,32 @@ func Check(Db *sqlx.DB, connectionString string) bool {
return false
}
{ // check minimum MySQL version as we need JSON column type. 5.7.10
vParts := strings.Split(version, ".")
if len(vParts) < 3 {
log.Error("MySQL version not of the form a.b.c:", errors.New(version))
web.SiteInfo.Issue = "MySQL version in the wrong format: " + version
// Get SQL variant as this affects minimum version checking logic.
// MySQL and Percona share same version scheme (e..g 5.7.10).
// MariaDB starts at 10.2.x
sqlVariant := GetSQLVariant(dbComment)
log.Info("SQL variant: " + sqlVariant)
log.Info("SQL version: " + version)
verNums, err := GetSQLVersion(version)
if err != nil {
log.Error("Database version check failed", err)
}
// Check minimum MySQL version as we need JSON column type.
verInts := []int{5, 7, 10} // Minimum MySQL version
if sqlVariant == sqlVariantMariaDB {
verInts = []int{10, 2, 0} // Minimum MariaDB version
}
for k, v := range verInts {
if verNums[k] < v {
want := fmt.Sprintf("%d.%d.%d", verInts[0], verInts[1], verInts[2])
log.Error("MySQL version element "+strconv.Itoa(k+1)+" of '"+version+"' not high enough, need at least version "+want, errors.New("bad MySQL version"))
web.SiteInfo.Issue = "MySQL version element " + strconv.Itoa(k+1) + " of '" + version + "' not high enough, need at least version " + want
web.SiteMode = web.SiteModeBadDB
return false
}
verInts := []int{5, 7, 10} // Minimum MySQL version
for k, v := range verInts {
i := ExtractVersionNumber(vParts[k])
// i, err := strconv.Atoi(vParts[k])
// if err != nil {
// log.Error("MySQL version element "+strconv.Itoa(k+1)+" of '"+version+"' not an integer:", err)
// web.SiteInfo.Issue = "MySQL version element " + strconv.Itoa(k+1) + " of '" + version + "' not an integer: " + err.Error()
// web.SiteMode = web.SiteModeBadDB
// return false
// }
if i < v {
want := fmt.Sprintf("%d.%d.%d", verInts[0], verInts[1], verInts[2])
log.Error("MySQL version element "+strconv.Itoa(k+1)+" of '"+version+"' not high enough, need at least version "+want, errors.New("bad MySQL version"))
web.SiteInfo.Issue = "MySQL version element " + strconv.Itoa(k+1) + " of '" + version + "' not high enough, need at least version " + want
web.SiteMode = web.SiteModeBadDB
return false
}
}
}
{ // check the MySQL character set and collation
@ -147,34 +152,45 @@ func Check(Db *sqlx.DB, connectionString string) bool {
return true
}
// ExtractVersionNumber checks and sends back an integer.
// MySQL can have version numbers like 5.5.47-0ubuntu0.14.04.1
func ExtractVersionNumber(s string) (num int) {
num = 0
// GetSQLVariant uses database value form @@version_comment to deduce MySQL variant.
func GetSQLVariant(vc string) string {
vc = strings.ToLower(vc)
// deal with build suffixes
// http://dba.stackexchange.com/questions/63763/is-there-any-difference-between-these-two-version-of-mysql-5-1-73-community-lo
s = strings.Replace(s, "-log", "", 1)
s = strings.Replace(s, "-debug", "", 1)
s = strings.Replace(s, "-demo", "", 1)
if strings.Contains(vc, "mariadb") {
return sqlVariantMariaDB
} else if strings.Contains(vc, "percona") {
return sqlVariantPercona
} else if strings.Contains(vc, "mysql") {
return sqlVariantMySQL
}
// convert to number
num, err := strconv.Atoi(s)
return "UNKNOWN"
}
if err != nil {
num = 0
// probably found "47-0ubuntu0.14.04.1" so we need to lose everything after the hypen
pos := strings.Index(s, "-")
if pos > 1 {
num, err = strconv.Atoi(s[:pos])
}
// GetSQLVersion returns SQL version as major,minor,patch numerics.
func GetSQLVersion(v string) (ints []int, err error) {
ints = []int{0, 0, 0}
pos := strings.Index(v, "-")
if pos > 1 {
v = v[:pos]
}
vs := strings.Split(v, ".")
if len(vs) < 3 {
err = errors.New("MySQL version not of the form a.b.c")
return
}
for key, val := range vs {
num, err := strconv.Atoi(val)
if err != nil {
num = 0
log.Error("MySQL version element '"+s+"' not an integer:", err)
web.SiteInfo.Issue = "MySQL version element '" + s + "' not an integer: " + err.Error()
web.SiteMode = web.SiteModeBadDB
return ints, err
}
ints[key] = num
}
return

View file

@ -13,19 +13,48 @@ package database
import "testing"
// go test github.com/documize/community/core/database -run TestVersionExtract
func TestVersionExtract(t *testing.T) {
ts(t, "5", 5)
ts(t, "45-0ubuntu0-12.12.3", 45)
ts(t, "untu0-12.12.3", 0)
ts(t, "junk-string", 0)
ts(t, "somethingstring", 0)
//
// // go test github.com/documize/community/core/database -run TestVersionExtract
// func TestVersionExtract(t *testing.T) {
// ts(t, "5", 5)
// ts(t, "45-0ubuntu0-12.12.3", 45)
// ts(t, "untu0-12.12.3", 0)
// ts(t, "junk-string", 0)
// ts(t, "somethingstring", 0)
// }
//
// func ts(t *testing.T, in string, out int) {
// got := ExtractVersionNumber(in)
//
// if got != out {
// t.Errorf("version input `%s` got `%d` expected `%d`\n", in, got, out)
// }
// }
// go test github.com/documize/community/core/database -run TestGetVersion
func TestGetVersion(t *testing.T) {
ts2(t, "5.7.10", []int{5, 7, 10})
ts2(t, "5.7.10-log", []int{5, 7, 10})
ts2(t, "5.7.10-demo", []int{5, 7, 10})
ts2(t, "5.7.10-debug", []int{5, 7, 10})
ts2(t, "5.7.16-10", []int{5, 7, 16})
ts2(t, "5.7.12-0ubuntu0-12.12.3", []int{5, 7, 12})
ts2(t, "10.1.20-MariaDB-1~jessie", []int{10, 1, 20})
ts2(t, "ubuntu0-12.12.3", []int{0, 0, 0})
ts2(t, "junk-string", []int{0, 0, 0})
ts2(t, "somethingstring", []int{0, 0, 0})
}
func ts(t *testing.T, in string, out int) {
got := ExtractVersionNumber(in)
func ts2(t *testing.T, in string, out []int) {
got, _ := GetSQLVersion(in)
if got != out {
t.Errorf("version input `%s` got `%d` expected `%d`\n", in, got, out)
// if err != nil {
// t.Errorf("Unable to GetSQLVersion %s", err)
// }
for k, v := range got {
if v != out[k] {
t.Errorf("version input of %s got %d for position %d but expected %d\n", in, v, k, out[k])
}
}
}

View file

@ -26,7 +26,7 @@ type ProdInfo struct {
// Product returns product edition details
func Product() (p ProdInfo) {
p.Major = "0"
p.Minor = "38"
p.Minor = "39"
p.Patch = "0"
p.Version = fmt.Sprintf("%s.%s.%s", p.Major, p.Minor, p.Patch)
p.Edition = "Community"

File diff suppressed because one or more lines are too long

View file

@ -3,5 +3,5 @@
"target": "es6",
"experimentalDecorators": true
},
"exclude": ["node_modules", "bower_components", "tmp", "vendor", ".git", "dist"]
"exclude": ["node_modules", "bower_components", "tmp", "vendor", ".git", "dist", "dist-prod"]
}