1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 05:09:42 +02:00

Accept activation key during setup process

Enterprise edition only.
This commit is contained in:
sauls8t 2019-06-19 12:46:05 +01:00
parent 887c999a1e
commit 4d2f30711c
11 changed files with 161 additions and 52 deletions

View file

@ -12,6 +12,8 @@
package database
import (
"encoding/json"
"encoding/xml"
"errors"
"net/http"
"time"
@ -21,6 +23,7 @@ import (
"github.com/documize/community/core/secrets"
"github.com/documize/community/core/stringutil"
"github.com/documize/community/core/uniqueid"
"github.com/documize/community/domain"
"github.com/documize/community/domain/store"
"github.com/documize/community/server/web"
)
@ -65,15 +68,16 @@ func (h *Handler) Setup(w http.ResponseWriter, r *http.Request) {
}
details := onboardRequest{
URL: "",
Company: r.Form.Get("title"),
CompanyLong: r.Form.Get("title"),
Message: r.Form.Get("message"),
Email: r.Form.Get("email"),
Password: r.Form.Get("password"),
Firstname: r.Form.Get("firstname"),
Lastname: r.Form.Get("lastname"),
Revised: time.Now().UTC(),
URL: "",
Company: r.Form.Get("title"),
CompanyLong: r.Form.Get("title"),
Message: r.Form.Get("message"),
Email: r.Form.Get("email"),
Password: r.Form.Get("password"),
Firstname: r.Form.Get("firstname"),
Lastname: r.Form.Get("lastname"),
ActivationKey: r.Form.Get("activationKey"),
Revised: time.Now().UTC(),
}
if details.Company == "" ||
@ -108,15 +112,16 @@ func (h *Handler) Setup(w http.ResponseWriter, r *http.Request) {
// The result of completing the onboarding process.
type onboardRequest struct {
URL string
Company string
CompanyLong string
Message string
Email string
Password string
Firstname string
Lastname string
Revised time.Time
URL string
Company string
CompanyLong string
Message string
Email string
Password string
Firstname string
Lastname string
ActivationKey string
Revised time.Time
}
// setupAccount prepares the database for a newly onboard customer.
@ -132,10 +137,14 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er
salt := secrets.GenerateSalt()
password := secrets.GeneratePassword(completion.Password, salt)
// Process activation key if we have one.
activationKey := processActivationKey(rt, completion)
// Allocate organization to the user.
orgID := uniqueid.Generate()
_, err = tx.Exec(RebindParams("INSERT INTO dmz_org (c_refid, c_company, c_title, c_message, c_domain, c_email, c_serial) VALUES (?, ?, ?, ?, ?, ?, ?)", rt.StoreProvider.Type()),
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial)
_, err = tx.Exec(RebindParams("INSERT INTO dmz_org (c_refid, c_company, c_title, c_message, c_domain, c_email, c_serial, c_sub) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
rt.StoreProvider.Type()),
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial, activationKey)
if err != nil {
rt.Log.Error("INSERT INTO dmz_org failed", err)
tx.Rollback()
@ -243,3 +252,30 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er
return
}
func processActivationKey(rt *env.Runtime, or onboardRequest) (key string) {
key = "{}"
if len(or.ActivationKey) == 0 {
return
}
j := domain.SubscriptionData{}
x := domain.SubscriptionXML{Key: "", Signature: ""}
err1 := xml.Unmarshal([]byte(or.ActivationKey), &x)
if err1 == nil {
j.Key = x.Key
j.Signature = x.Signature
} else {
rt.Log.Error("failed to XML unmarshal subscription XML", err1)
}
d, err2 := json.Marshal(j)
if err2 == nil {
key = string(d)
} else {
rt.Log.Error("failed to JSON marshal subscription XML", err2)
}
return
}

View file

@ -0,0 +1,34 @@
// 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 { inject as service } from '@ember/service';
import Modals from '../../mixins/modal';
import Component from '@ember/component';
export default Component.extend(Modals, {
localStorage: service(),
didReceiveAttrs() {
this._super(...arguments);
let firstRun = this.get('localStorage').isFirstRun();
if (firstRun) {
this.modalOpen('#first-run-modal', {'show': true});
}
},
actions: {
onCloseModal() {
this.modalClose('#first-run-modal');
}
}
});

View file

@ -7,6 +7,7 @@
<title>Documize</title>
<meta property="dbname" content="{{.DBname}}" />
<meta property="dbhash" content="{{.DBhash}}" />
<meta property="edition" content="{{.Edition}}" />
<meta name="author" content="Documize" />
<meta name="description" content="Documize">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

View file

@ -16,8 +16,12 @@ export default Route.extend({
session: service(),
localStorage: service(),
beforeModel() {
beforeModel(transition) {
this.get('localStorage').clearAll();
if (!_.isUndefined(transition.to.queryParams.fr)) {
this.get('localStorage').setFirstRun();
}
},
model({ token }) {

View file

@ -1,4 +1,4 @@
<div class="sso-box">
<p>Signing in...</p>
<img src="/assets/img/busy-gray.gif">
<img src="/assets/img/busy-gray.gif" alt="busy">
</div>

View file

@ -23,10 +23,10 @@ export default Controller.extend({
data: this.model,
dataType: "text",
}).then(() => {
let dom = ""; // supports http://localhost:5001 installations (which is the default for all self-installs)
var credentials = Encoding.Base64.encode(dom + ":" + this.model.email + ":" + this.model.password);
window.location.href = "/auth/sso/" + encodeURIComponent(credentials);
}).catch((error) => { // eslint-disable-line no-unused-vars
let dom = ""; // supports http://localhost:5001 installs (which is the default for all self-installs)
let credentials = Encoding.Base64.encode(dom + ":" + this.model.email + ":" + this.model.password);
window.location.href = "/auth/sso/" + encodeURIComponent(credentials) + '?fr=1';
}).catch((/*error*/) => {
// TODO notify user of the error within the GUI
});
}

View file

@ -33,7 +33,9 @@ export default Route.extend({
firstname: "",
lastname: "",
email: "",
password: pwd
password: pwd,
activationKey: '',
edition: document.head.querySelector("[property=edition]").content
};
},

View file

@ -59,10 +59,12 @@ export default Service.extend({
let isInSetupMode = dbhash && dbhash !== "{{.DBhash}}";
if (isInSetupMode) {
let edition = document.head.querySelector("[property=edition]");
this.setProperties({
title: htmlSafe("Documize Setup"),
allowAnonymousAccess: true,
setupMode: true
setupMode: true,
edition: !_.isNull(edition) ? edition : 'Community'
});
this.get('localStorage').clearAll();

View file

@ -12,22 +12,23 @@
import Service from '@ember/service';
export default Service.extend({
storeSessionItem: function (key, data) {
localStorage[key] = data;
},
getSessionItem: function (key) {
return localStorage[key];
},
clearSessionItem: function (key) {
delete localStorage[key];
},
// Remove all items from storage.
clearAll() {
localStorage.clear();
},
// Generic session item CRUD methods.
storeSessionItem: function (key, data) {
localStorage[key] = data;
},
getSessionItem: function (key) {
return localStorage[key];
},
clearSessionItem: function (key) {
delete localStorage[key];
},
// Per document expand/collapse state.
getDocSectionHide(docId) {
let state = localStorage[`doc-hide-${docId}`];
if (_.isUndefined(state) || _.isEmpty(state)) {
@ -36,7 +37,6 @@ export default Service.extend({
return _.split(state, '|');
},
setDocSectionHide(docId, state) {
let key = `doc-hide-${docId}`;
@ -46,4 +46,15 @@ export default Service.extend({
localStorage[key] = _.join(state, '|');
}
},
// First run wizard.
setFirstRun() {
localStorage['firstRun'] = true;
},
isFirstRun() {
return !_.isUndefined(localStorage['firstRun']);
},
unsetFirstRun() {
delete localStorage['firstRun'];
}
});

View file

@ -1,7 +1,7 @@
<div class="installer">
<img src="/assets/img/setup/logo-purple.png" srcset="/assets/img/setup/logo-purple@2x.png" alt="Documize Setup" style="width: 250px; height: 76px;">
<Ui::UiSpacer @size="300" />
<h1 class="color-theme-700">Installation Guide</h1>
<h1 class="color-theme-700">Setup</h1>
<p class="color-gray-800">
Review the <a href="https://docs.documize.com/s/VzO9ZqMOCgABGyfW/installation-guides/d/V16L08ucxwABhZF6/installation-guide">installation instructions</a>
and recommended <a href="https://docs.documize.com/s/VzO9ZqMOCgABGyfW/installation-guides/d/V2KuM8ICcQABagM5/mysql-specific-database-tuning">database tuning guide</a>
@ -11,27 +11,33 @@
<form {{action "save" on="submit"}}>
<div class="form-group">
<label>Site name</label>
{{focus-input id="siteTitle" type="text" value=model.title class=(if hasEmptyTitleError "form-control is-invalid" "form-control")}}
{{focus-input id="setup-title" type="text" value=model.title class=(if hasTitleError "form-control is-invalid" "form-control")}}
<small class="form-text text-muted">Usually your company or team name</small>
</div>
<div class="form-group">
<label for="adminFirstname">Firstname</label>
{{input id="adminFirstname" type="text" value=model.firstname class=(if hasEmptyFirstnameError "form-control is-invalid" "form-control")}}
<label for="setup-firstname">Firstname</label>
{{input id="setup-firstname" type="text" value=model.firstname class=(if hasFirstnameError "form-control is-invalid" "form-control")}}
</div>
<div class="form-group">
<label for="adminLastname">Lastname</label>
{{input id="adminLastname" type="text" value=model.lastname class=(if hasEmptyLastnameError "form-control is-invalid" "form-control")}}
<label for="setup-lastname">Lastname</label>
{{input id="setup-lastname" type="text" value=model.lastname class=(if hasLastnameError "form-control is-invalid" "form-control")}}
</div>
<div class="form-group">
<label for="adminEmail">Email</label>
{{input id="adminEmail" type="email" value=model.email class=(if hasEmptyEmailError "form-control is-invalid" "form-control")}}
<small class="form-text text-muted">No spam. Ever.</small>
<label for="setup-email">Email</label>
{{input id="setup-email" type="email" value=model.email class=(if hasEmailError "form-control is-invalid" "form-control")}}
</div>
<div class="form-group">
<label for="adminPassword">Password</label>
{{input id="adminPassword" type="password" value=model.password class=(if hasEmptyPasswordError "form-control is-invalid" "form-control")}}
<label for="new-password">Password</label>
{{input id="new-password" type="password" value=model.password class=(if hasPasswordError "form-control is-invalid" "form-control")}}
<small class="form-text text-muted">Pick something strong and unique that you don't use anywhere else</small>
</div>
{{#if (eq model.edition constants.Product.EnterpriseEdition)}}
<div class="form-group">
<label for="activation-key">Activation Key</label>
{{textarea id="activation-key" value=model.activationKey rows="5" class=(if hasKeyError "form-control is-invalid" "form-control")}}
<small class="form-text text-muted">You can get it from <a href="https://www.documize.com/downloads" target="_blank">https://www.documize.com/downloads</a></small>
</div>
{{/if}}
{{ui/ui-button submit=true color=constants.Color.Green light=true label=buttonLabel onClick=(action "save")}}
</form>

View file

@ -0,0 +1,13 @@
<div id="first-run-modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">Getting Started</div>
<div class="modal-body">
<p>dfdfdf</p>
</div>
<div class="modal-footer">
{{ui/ui-button color=constants.Color.Yellow light=true label="Got it!" dismiss=true}}
</div>
</div>
</div>
</div>