1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-21 14:19:43 +02:00

support for persona 5.7+ and prep'ed support for MariaDB 10.2+

This commit is contained in:
Harvey Kandola 2017-01-17 15:30:39 +00:00
parent f12cdfbd45
commit e31c6e12a2
13 changed files with 768 additions and 682 deletions

1
.gitignore vendored
View file

@ -62,3 +62,4 @@ debug
Dockerfile Dockerfile
container.sh container.sh
make.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, { export default Ember.Route.extend(AuthenticatedRouteMixin, {
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
model: function () { model() {
return this.get('folderService').getAll(); return this.get('folderService').getAll();
} }
}); });

View file

@ -39,9 +39,10 @@ export default Ember.Route.extend(ApplicationRouteMixin, TooltipMixin, {
this.destroyTooltips(); this.destroyTooltips();
}, },
error(error /*, transition*/ ) { error(error, transition) {
if (error) { if (error) {
console.log(error); console.log(error);
console.log(transition);
if (netUtil.isAjaxAccessError(error)) { if (netUtil.isAjaxAccessError(error)) {
localStorage.clear(); 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 domain = request.CheckDomain(domain) // TODO optimize by removing this once js allows empty domains
email := strings.TrimSpace(strings.ToLower(credentials[1])) email := strings.TrimSpace(strings.ToLower(credentials[1]))
password := credentials[2] password := credentials[2]
log.Info("logon attempt for " + domain + " @ " + email) log.Info("logon attempt " + email + " @ " + domain)
user, err := p.GetUserByDomain(domain, email) 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) 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) writeUnauthorizedError(w)
return return
} }

View file

@ -32,7 +32,7 @@ func (p *Persister) AddDocument(document entity.Document) (err error) {
document.Layout = "doc" 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) defer utility.Close(stmt)
if err != nil { if err != nil {

View file

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

View file

@ -13,19 +13,48 @@ package database
import "testing" import "testing"
// go test github.com/documize/community/core/database -run TestVersionExtract //
func TestVersionExtract(t *testing.T) { // // go test github.com/documize/community/core/database -run TestVersionExtract
ts(t, "5", 5) // func TestVersionExtract(t *testing.T) {
ts(t, "45-0ubuntu0-12.12.3", 45) // ts(t, "5", 5)
ts(t, "untu0-12.12.3", 0) // ts(t, "45-0ubuntu0-12.12.3", 45)
ts(t, "junk-string", 0) // ts(t, "untu0-12.12.3", 0)
ts(t, "somethingstring", 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) { func ts2(t *testing.T, in string, out []int) {
got := ExtractVersionNumber(in) got, _ := GetSQLVersion(in)
if got != out { // if err != nil {
t.Errorf("version input `%s` got `%d` expected `%d`\n", in, got, out) // 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 // Product returns product edition details
func Product() (p ProdInfo) { func Product() (p ProdInfo) {
p.Major = "0" p.Major = "0"
p.Minor = "38" p.Minor = "39"
p.Patch = "0" p.Patch = "0"
p.Version = fmt.Sprintf("%s.%s.%s", p.Major, p.Minor, p.Patch) p.Version = fmt.Sprintf("%s.%s.%s", p.Major, p.Minor, p.Patch)
p.Edition = "Community" p.Edition = "Community"

File diff suppressed because one or more lines are too long

View file

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