diff --git a/.gitignore b/.gitignore index 1c89c99c..c30a2b41 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,6 @@ npm-debug.log debug *.pem *.crt -Dockerfile container.sh make.sh jsconfig.json diff --git a/core/database/setup_endpoint.go b/core/database/setup_endpoint.go index 7027e002..6491dc1a 100644 --- a/core/database/setup_endpoint.go +++ b/core/database/setup_endpoint.go @@ -131,7 +131,7 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er // Allocate organization to the user. orgID := uniqueid.Generate() - sql := fmt.Sprintf("insert into organization (refid, company, title, message, domain, email, serial) values (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\")", + sql := fmt.Sprintf("insert into dmz_org (c_refid, c_company, c_title, c_message, c_domain, c_email, c_serial) VALUES (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\")", orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial) _, err = runSQL(rt, sql) @@ -142,7 +142,7 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er userID := uniqueid.Generate() - sql = fmt.Sprintf("insert into user (refid, firstname, lastname, email, initials, salt, password, global) values (\"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", 1)", + sql = fmt.Sprintf("INSERT INTO dmz_user (c_refid, c_firstname, c_lastname, c_email, c_initials, c_salt, c_password, c_globaladmin) VALUES (\"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", 1)", userID, completion.Firstname, completion.Lastname, completion.Email, stringutil.MakeInitials(completion.Firstname, completion.Lastname), salt, password) _, err = runSQL(rt, sql) @@ -153,7 +153,7 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er // Link user to organization. accountID := uniqueid.Generate() - sql = fmt.Sprintf("insert into account (refid, userid, orgid, `admin`, editor, users, analytics) values (\"%s\", \"%s\", \"%s\", 1, 1, 1, 1)", accountID, userID, orgID) + sql = fmt.Sprintf("INSERT INTO dmz_user_account (c_refid, c_userid, c_orgid, c_admin, c_editor, c_users, c_analytics) VALUES (\"%s\", \"%s\", \"%s\", 1, 1, 1, 1)", accountID, userID, orgID) _, err = runSQL(rt, sql) if err != nil { @@ -163,59 +163,59 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er // create space labelID := uniqueid.Generate() - sql = fmt.Sprintf("insert into label (refid, orgid, label, type, userid) values (\"%s\", \"%s\", \"My Project\", 2, \"%s\")", labelID, orgID, userID) + sql = fmt.Sprintf("INSERT INTO dmz_space (c_refid, c_orgid, c_name, c_type, c_userid) VALUES (\"%s\", \"%s\", \"My Project\", 2, \"%s\")", labelID, orgID, userID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into label failed", err) + rt.Log.Error("INSERT INTO label failed", err) } // assign permissions to space perms := []string{"view", "manage", "own", "doc-add", "doc-edit", "doc-delete", "doc-move", "doc-copy", "doc-template", "doc-approve", "doc-version", "doc-lifecycle"} for _, p := range perms { - sql = fmt.Sprintf("insert into permission (orgid, who, whoid, action, scope, location, refid) values (\"%s\", 'user', \"%s\", \"%s\", 'object', 'space', \"%s\")", orgID, userID, p, labelID) + sql = fmt.Sprintf("INSERT INTO dmz_permission (c_orgid, c_who, c_whoid, c_action, c_scope, c_location, c_refid) VALUES (\"%s\", 'user', \"%s\", \"%s\", 'object', 'space', \"%s\")", orgID, userID, p, labelID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into permission failed", err) + rt.Log.Error("INSERT INTO permission failed", err) } } // Create some user groups groupDevID := uniqueid.Generate() - sql = fmt.Sprintf("INSERT INTO role (refid, orgid, role, purpose) VALUES (\"%s\", \"%s\", \"Technology\", \"On-site and remote development teams\")", groupDevID, orgID) + sql = fmt.Sprintf("INSERT INTO group (c_refid, c_orgid, c_name, c_desc) VALUES (\"%s\", \"%s\", \"Technology\", \"On-site and remote development teams\")", groupDevID, orgID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into role failed", err) + rt.Log.Error("INSERT INTO group failed", err) } groupProjectID := uniqueid.Generate() - sql = fmt.Sprintf("INSERT INTO role (refid, orgid, role, purpose) VALUES (\"%s\", \"%s\", \"Project Management\", \"HQ project management\")", groupProjectID, orgID) + sql = fmt.Sprintf("INSERT INTO group (c_refid, c_orgid, c_name, c_desc) VALUES (\"%s\", \"%s\", \"Project Management\", \"HQ project management\")", groupProjectID, orgID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into role failed", err) + rt.Log.Error("INSERT INTO group failed", err) } groupBackofficeID := uniqueid.Generate() - sql = fmt.Sprintf("INSERT INTO role (refid, orgid, role, purpose) VALUES (\"%s\", \"%s\", \"Back Office\", \"Non-IT and PMO personnel\")", groupBackofficeID, orgID) + sql = fmt.Sprintf("INSERT INTO group (c_refid, c_orgid, c_name, c_desc) VALUES (\"%s\", \"%s\", \"Back Office\", \"Non-IT and PMO personnel\")", groupBackofficeID, orgID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into role failed", err) + rt.Log.Error("INSERT INTO group failed", err) } // Join some groups - sql = fmt.Sprintf("INSERT INTO rolemember (orgid, roleid, userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupDevID, userID) + sql = fmt.Sprintf("INSERT INTO dmz_group_member (c_orgid, c_groupid, c_userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupDevID, userID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into rolemember failed", err) + rt.Log.Error("INSERT INTO dmz_group_member failed", err) } - sql = fmt.Sprintf("INSERT INTO rolemember (orgid, roleid, userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupProjectID, userID) + sql = fmt.Sprintf("INSERT INTO dmz_group_member (c_orgid, c_groupid, c_userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupProjectID, userID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into rolemember failed", err) + rt.Log.Error("INSERT INTO dmz_group_member failed", err) } - sql = fmt.Sprintf("INSERT INTO rolemember (orgid, roleid, userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupBackofficeID, userID) + sql = fmt.Sprintf("INSERT INTO dmz_group_member (c_orgid, c_groupid, c_userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupBackofficeID, userID) _, err = runSQL(rt, sql) if err != nil { - rt.Log.Error("insert into rolemember failed", err) + rt.Log.Error("INSERT INTO dmz_group_member failed", err) } return diff --git a/domain/document/mysql/store.go b/domain/document/mysql/store.go index ce848d30..08a6f7af 100644 --- a/domain/document/mysql/store.go +++ b/domain/document/mysql/store.go @@ -178,12 +178,8 @@ func (s Scope) TemplatesBySpace(ctx domain.RequestContext, spaceID string) (docu // These documents can then be seen by search crawlers. func (s Scope) PublicDocuments(ctx domain.RequestContext, orgID string) (documents []doc.SitemapDocument, err error) { err = s.Runtime.Db.Select(&documents, ` - SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_userid AS userid, - c_job AS job, c_location AS location, c_name AS name, c_desc AS excerpt, c_slug AS slug, - c_tags AS tags, c_template AS template, c_protection AS protection, c_approval AS approval, - c_lifecycle AS lifecycle, c_versioned AS versioned, c_versionid AS versionid, - c_versionorder AS versionorder, c_groupid AS groupid, c_created AS created, c_revised AS revised - FROM dmz_doc + SELECT d.c_refid AS documentid, d.c_name AS document, d.c_revised as revised, l.c_refid AS spaceid, l.c_name AS space + FROM dmz_doc d LEFT JOIN dmz_space l ON l.c_refid=d.c_spaceid WHERE d.c_orgid=? AND l.c_type=1 AND d.c_lifecycle=1 AND d.c_template=0`, orgID) @@ -192,12 +188,16 @@ func (s Scope) PublicDocuments(ctx domain.RequestContext, orgID string) (documen documents = []doc.SitemapDocument{} } if err != nil { - err = errors.Wrap(err, fmt.Sprintf("execute GetPublicDocuments for org %s%s", orgID)) + err = errors.Wrap(err, fmt.Sprintf("execute GetPublicDocuments for org %s", orgID)) } return } +/* + FROM document d LEFT JOIN label l ON l.refid=d.labelid +*/ + // Update changes the given document record to the new values, updates search information and audits the action. func (s Scope) Update(ctx domain.RequestContext, document doc.Document) (err error) { document.Revised = time.Now().UTC() diff --git a/domain/meta/endpoint.go b/domain/meta/endpoint.go index 5e953dff..43da2ee8 100644 --- a/domain/meta/endpoint.go +++ b/domain/meta/endpoint.go @@ -91,23 +91,24 @@ func (h *Handler) RobotsTxt(w http.ResponseWriter, r *http.Request) { // Anonymous access would mean we allow bots to crawl. if o.AllowAnonymousAccess { sitemap := ctx.GetAppURL("sitemap.xml") - robots = fmt.Sprintf( - `User-agent: * - Disallow: /settings/ - Disallow: /settings/* - Disallow: /profile/ - Disallow: /profile/* - Disallow: /auth/login/ - Disallow: /auth/login/ - Disallow: /auth/logout/ - Disallow: /auth/logout/* - Disallow: /auth/reset/* - Disallow: /auth/reset/* - Disallow: /auth/sso/ - Disallow: /auth/sso/* - Disallow: /share - Disallow: /share/* - Sitemap: %s`, sitemap) + robots = fmt.Sprintf(`User-agent: * +Disallow: /settings/ +Disallow: /settings/* +Disallow: /profile/ +Disallow: /profile/* +Disallow: /auth/login/ +Disallow: /auth/login/ +Disallow: /auth/logout/ +Disallow: /auth/logout/* +Disallow: /auth/reset/* +Disallow: /auth/reset/* +Disallow: /auth/sso/ +Disallow: /auth/sso/* +Disallow: /auth/* +Disallow: /auth/** +Disallow: /share +Disallow: /share/* +Sitemap: %s`, sitemap) } response.WriteBytes(w, []byte(robots)) @@ -166,7 +167,7 @@ func (h *Handler) Sitemap(w http.ResponseWriter, r *http.Request) { for _, document := range documents { var item sitemapItem item.URL = ctx.GetAppURL(fmt.Sprintf("s/%s/%s/d/%s/%s", - document.SpaceID, stringutil.MakeSlug(document.Folder), document.DocumentID, stringutil.MakeSlug(document.Document))) + document.SpaceID, stringutil.MakeSlug(document.Space), document.DocumentID, stringutil.MakeSlug(document.Document))) item.Date = document.Revised.Format("2006-01-02T15:04:05.999999-07:00") items = append(items, item) } diff --git a/gui/public/codemirror/mode/dockerfile/dockerfile.js b/gui/public/codemirror/mode/dockerfile/dockerfile.js new file mode 100644 index 00000000..769e787e --- /dev/null +++ b/gui/public/codemirror/mode/dockerfile/dockerfile.js @@ -0,0 +1,211 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/simple"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var from = "from"; + var fromRegex = new RegExp("^(\\s*)\\b(" + from + ")\\b", "i"); + + var shells = ["run", "cmd", "entrypoint", "shell"]; + var shellsAsArrayRegex = new RegExp("^(\\s*)(" + shells.join('|') + ")(\\s+\\[)", "i"); + + var expose = "expose"; + var exposeRegex = new RegExp("^(\\s*)(" + expose + ")(\\s+)", "i"); + + var others = [ + "arg", "from", "maintainer", "label", "env", + "add", "copy", "volume", "user", + "workdir", "onbuild", "stopsignal", "healthcheck", "shell" + ]; + + // Collect all Dockerfile directives + var instructions = [from, expose].concat(shells).concat(others), + instructionRegex = "(" + instructions.join('|') + ")", + instructionOnlyLine = new RegExp("^(\\s*)" + instructionRegex + "(\\s*)(#.*)?$", "i"), + instructionWithArguments = new RegExp("^(\\s*)" + instructionRegex + "(\\s+)", "i"); + + CodeMirror.defineSimpleMode("dockerfile", { + start: [ + // Block comment: This is a line starting with a comment + { + regex: /^\s*#.*$/, + sol: true, + token: "comment" + }, + { + regex: fromRegex, + token: [null, "keyword"], + sol: true, + next: "from" + }, + // Highlight an instruction without any arguments (for convenience) + { + regex: instructionOnlyLine, + token: [null, "keyword", null, "error"], + sol: true + }, + { + regex: shellsAsArrayRegex, + token: [null, "keyword", null], + sol: true, + next: "array" + }, + { + regex: exposeRegex, + token: [null, "keyword", null], + sol: true, + next: "expose" + }, + // Highlight an instruction followed by arguments + { + regex: instructionWithArguments, + token: [null, "keyword", null], + sol: true, + next: "arguments" + }, + { + regex: /./, + token: null + } + ], + from: [ + { + regex: /\s*$/, + token: null, + next: "start" + }, + { + // Line comment without instruction arguments is an error + regex: /(\s*)(#.*)$/, + token: [null, "error"], + next: "start" + }, + { + regex: /(\s*\S+\s+)(as)/i, + token: [null, "keyword"], + next: "start" + }, + // Fail safe return to start + { + token: null, + next: "start" + } + ], + single: [ + { + regex: /(?:[^\\']|\\.)/, + token: "string" + }, + { + regex: /'/, + token: "string", + pop: true + } + ], + double: [ + { + regex: /(?:[^\\"]|\\.)/, + token: "string" + }, + { + regex: /"/, + token: "string", + pop: true + } + ], + array: [ + { + regex: /\]/, + token: null, + next: "start" + }, + { + regex: /"(?:[^\\"]|\\.)*"?/, + token: "string" + } + ], + expose: [ + { + regex: /\d+$/, + token: "number", + next: "start" + }, + { + regex: /[^\d]+$/, + token: null, + next: "start" + }, + { + regex: /\d+/, + token: "number" + }, + { + regex: /[^\d]+/, + token: null + }, + // Fail safe return to start + { + token: null, + next: "start" + } + ], + arguments: [ + { + regex: /^\s*#.*$/, + sol: true, + token: "comment" + }, + { + regex: /"(?:[^\\"]|\\.)*"?$/, + token: "string", + next: "start" + }, + { + regex: /"/, + token: "string", + push: "double" + }, + { + regex: /'(?:[^\\']|\\.)*'?$/, + token: "string", + next: "start" + }, + { + regex: /'/, + token: "string", + push: "single" + }, + { + regex: /[^#"']+[\\`]$/, + token: null + }, + { + regex: /[^#"']+$/, + token: null, + next: "start" + }, + { + regex: /[^#"']+/, + token: null + }, + // Fail safe return to start + { + token: null, + next: "start" + } + ], + meta: { + lineComment: "#" + } + }); + + CodeMirror.defineMIME("text/x-dockerfile", "dockerfile"); +}); diff --git a/gui/public/codemirror/mode/dockerfile/index.html b/gui/public/codemirror/mode/dockerfile/index.html new file mode 100644 index 00000000..a31759bc --- /dev/null +++ b/gui/public/codemirror/mode/dockerfile/index.html @@ -0,0 +1,73 @@ + + +CodeMirror: Dockerfile mode + + + + + + + + + + +
+

Dockerfile mode

+
+ + + +

Dockerfile syntax highlighting for CodeMirror. Depends on + the simplemode addon.

+ +

MIME types defined: text/x-dockerfile

+
diff --git a/gui/public/codemirror/mode/dockerfile/test.js b/gui/public/codemirror/mode/dockerfile/test.js new file mode 100644 index 00000000..9a2b89ad --- /dev/null +++ b/gui/public/codemirror/mode/dockerfile/test.js @@ -0,0 +1,128 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-dockerfile"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("simple_nodejs_dockerfile", + "[keyword FROM] node:carbon", + "[comment # Create app directory]", + "[keyword WORKDIR] /usr/src/app", + "[comment # Install app dependencies]", + "[comment # A wildcard is used to ensure both package.json AND package-lock.json are copied]", + "[comment # where available (npm@5+)]", + "[keyword COPY] package*.json ./", + "[keyword RUN] npm install", + "[keyword COPY] . .", + "[keyword EXPOSE] [number 8080] [number 3000]", + "[keyword ENV] NODE_ENV development", + "[keyword CMD] [[ [string \"npm\"], [string \"start\"] ]]"); + + // Ideally the last space should not be highlighted. + MT("instruction_without_args_1", + "[keyword CMD] "); + + MT("instruction_without_args_2", + "[comment # An instruction without args...]", + "[keyword ARG] [error #...is an error]"); + + MT("multiline", + "[keyword RUN] apt-get update && apt-get install -y \\", + " mercurial \\", + " subversion \\", + " && apt-get clean \\", + " && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*"); + + MT("from_comment", + " [keyword FROM] debian:stretch # I tend to use stable as that is more stable", + " [keyword FROM] debian:stretch [keyword AS] stable # I am even more stable", + " [keyword FROM] [error # this is an error]"); + + MT("from_as", + "[keyword FROM] golang:1.9.2-alpine3.6 [keyword AS] build", + "[keyword COPY] --from=build /bin/project /bin/project", + "[keyword ENTRYPOINT] [[ [string \"/bin/project\"] ]]", + "[keyword CMD] [[ [string \"--help\"] ]]"); + + MT("arg", + "[keyword ARG] VERSION=latest", + "[keyword FROM] busybox:$VERSION", + "[keyword ARG] VERSION", + "[keyword RUN] echo $VERSION > image_version"); + + MT("label", + "[keyword LABEL] com.example.label-with-value=[string \"foo\"]"); + + MT("label_multiline", + "[keyword LABEL] description=[string \"This text illustrates ]\\", + "[string that label-values can span multiple lines.\"]"); + + MT("maintainer", + "[keyword MAINTAINER] Foo Bar [string \"foo@bar.com\"] ", + "[keyword MAINTAINER] Bar Baz "); + + MT("env", + "[keyword ENV] BUNDLE_PATH=[string \"$GEM_HOME\"] \\", + " BUNDLE_APP_CONFIG=[string \"$GEM_HOME\"]"); + + MT("verify_keyword", + "[keyword RUN] add-apt-repository ppa:chris-lea/node.js"); + + MT("scripts", + "[comment # Set an entrypoint, to automatically install node modules]", + "[keyword ENTRYPOINT] [[ [string \"/bin/bash\"], [string \"-c\"], [string \"if [[ ! -d node_modules ]]; then npm install; fi; exec \\\"${@:0}\\\";\"] ]]", + "[keyword CMD] npm start", + "[keyword RUN] npm run build && \\", + "[comment # a comment between the shell commands]", + " npm run test"); + + MT("strings_single", + "[keyword FROM] buildpack-deps:stretch", + "[keyword RUN] { \\", + " echo [string 'install: --no-document']; \\", + " echo [string 'update: --no-document']; \\", + " } >> /usr/local/etc/gemrc"); + + MT("strings_single_multiline", + "[keyword RUN] set -ex \\", + " \\", + " && buildDeps=[string ' ]\\", + "[string bison ]\\", + "[string dpkg-dev ]\\", + "[string libgdbm-dev ]\\", + "[string ruby ]\\", + "[string '] \\", + " && apt-get update"); + + MT("strings_single_multiline_2", + "[keyword RUN] echo [string 'say \\' ]\\", + "[string it works'] "); + + MT("strings_double", + "[keyword RUN] apt-get install -y --no-install-recommends $buildDeps \\", + " \\", + " && wget -O ruby.tar.xz [string \"https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz\"] \\", + " && echo [string \"$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz\"] | sha256sum -c - "); + + MT("strings_double_multiline", + "[keyword RUN] echo [string \"say \\\" ]\\", + "[string it works\"] "); + + MT("escape", + "[comment # escape=`]", + "[keyword FROM] microsoft/windowsservercore", + "[keyword RUN] powershell.exe -Command `", + " $ErrorActionPreference = [string 'Stop']; `", + " wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; `", + " Start-Process c:\python-3.5.1.exe -ArgumentList [string '/quiet InstallAllUsers=1 PrependPath=1'] -Wait ; `", + " Remove-Item c:\python-3.5.1.exe -Force)"); + + MT("escape_strings", + "[comment # escape=`]", + "[keyword FROM] python:3.6-windowsservercore [keyword AS] python", + "[keyword RUN] $env:PATH = [string 'C:\\Python;C:\\Python\\Scripts;{0}'] -f $env:PATH ; `", + // It should not consider \' as escaped. + // " Set-ItemProperty -Path [string 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\'] -Name Path -Value $env:PATH ;"); + " Set-ItemProperty -Path [string 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\' -Name Path -Value $env:PATH ;]"); +})(); diff --git a/model/doc/doc.go b/model/doc/doc.go index 91e20958..5e2848f4 100644 --- a/model/doc/doc.go +++ b/model/doc/doc.go @@ -91,7 +91,7 @@ type SitemapDocument struct { DocumentID string Document string SpaceID string - Folder string + Space string Revised time.Time }