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:
parent
f12cdfbd45
commit
e31c6e12a2
13 changed files with 768 additions and 682 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -62,3 +62,4 @@ debug
|
||||||
Dockerfile
|
Dockerfile
|
||||||
container.sh
|
container.sh
|
||||||
make.sh
|
make.sh
|
||||||
|
jsconfig.json
|
14
app/app/pods/auth/sso/controller.js
Normal file
14
app/app/pods/auth/sso/controller.js
Normal 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({});
|
|
@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@ -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"]
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue