mirror of
https://github.com/documize/community.git
synced 2025-08-08 23:15:29 +02:00
Merge pull request #17 from documize/github-extension
Github extension - secrets WIP as requested
This commit is contained in:
commit
1436d37ff4
30 changed files with 918 additions and 689 deletions
|
@ -15,427 +15,441 @@ import TooltipMixin from '../../../mixins/tooltip';
|
||||||
import SectionMixin from '../../../mixins/section';
|
import SectionMixin from '../../../mixins/section';
|
||||||
|
|
||||||
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
|
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
|
||||||
sectionService: Ember.inject.service('section'),
|
sectionService: Ember.inject.service('section'),
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
busy: false,
|
busy: false,
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
config: {},
|
config: {},
|
||||||
owners: null,
|
owners: null,
|
||||||
repos: null,
|
repos: null,
|
||||||
noRepos: false,
|
noRepos: false,
|
||||||
showCommits: false,
|
showCommits: false,
|
||||||
showIssueNum: false,
|
showIssueNum: false,
|
||||||
showLabels: false,
|
showLabels: false,
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
let self = this;
|
let self = this;
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
|
|
||||||
if (is.undefined(this.get('config.clientId')) || is.undefined(this.get('config.callbackUrl'))) {
|
if (is.undefined(this.get('config.clientId')) || is.undefined(this.get('config.callbackUrl'))) {
|
||||||
self.get('sectionService').fetch(page, "config", {})
|
self.get('sectionService').fetch(page, "config", {})
|
||||||
.then(function(cfg) {
|
.then(function (cfg) {
|
||||||
let config = {};
|
let config = {};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
clientId: cfg.clientID,
|
clientId: cfg.clientID,
|
||||||
callbackUrl: cfg.authorizationCallbackURL,
|
callbackUrl: cfg.authorizationCallbackURL,
|
||||||
token: "",
|
owner: null,
|
||||||
owner: null,
|
owner_name: "",
|
||||||
owner_name: "",
|
repo: null,
|
||||||
repo: null,
|
repo_name: "",
|
||||||
repo_name: "",
|
report: null,
|
||||||
report: null,
|
lists: [],
|
||||||
lists: [],
|
branch: "",
|
||||||
branch: "",
|
branchURL: "",
|
||||||
branchURL: "",
|
branchSince: "",
|
||||||
branchSince: "",
|
branchLines: "30",
|
||||||
branchLines: "30",
|
state: null,
|
||||||
state: null,
|
issues: "",
|
||||||
issues: "",
|
userId: "",
|
||||||
};
|
pageId: page.get('id'),
|
||||||
|
};
|
||||||
try {
|
|
||||||
let metaConfig = JSON.parse(self.get('meta.config'));
|
try {
|
||||||
config.owner = metaConfig.owner;
|
let metaConfig = JSON.parse(self.get('meta.config'));
|
||||||
config.repo = metaConfig.repo;
|
config.owner = metaConfig.owner;
|
||||||
config.report = metaConfig.report;
|
config.repo = metaConfig.repo;
|
||||||
config.lists = metaConfig.lists;
|
config.report = metaConfig.report;
|
||||||
config.branchSince = metaConfig.branchSince;
|
config.lists = metaConfig.lists;
|
||||||
config.branchLines = metaConfig.branchLines;
|
config.branchSince = metaConfig.branchSince;
|
||||||
config.state = metaConfig.state;
|
config.branchLines = metaConfig.branchLines;
|
||||||
config.issues = metaConfig.issues;
|
config.state = metaConfig.state;
|
||||||
} catch (e) {}
|
config.issues = metaConfig.issues;
|
||||||
|
config.userId = metaConfig.userId;
|
||||||
self.set('config', config);
|
config.pageId = metaConfig.pageId;
|
||||||
|
} catch (e) {}
|
||||||
// On auth callback capture code
|
|
||||||
let code = window.location.search;
|
self.set('config', config);
|
||||||
|
self.set('config.pageId', page.get('id'));
|
||||||
if (is.not.undefined(code) && is.not.null(code)) {
|
|
||||||
let tok = code.replace("?code=", "");
|
// On auth callback capture code
|
||||||
if (is.not.empty(code)) {
|
let code = window.location.search;
|
||||||
self.set('config.token', tok);
|
|
||||||
self.send('authStage2');
|
if (is.not.undefined(code) && is.not.null(code) && is.not.empty(code) && code !== "") {
|
||||||
}
|
let tok = code.replace("?code=", "");
|
||||||
} else {
|
self.get('sectionService').fetch(page, "saveSecret", { "token": tok })
|
||||||
if (self.get('config.token') === "") {
|
.then(function () {
|
||||||
self.send('auth');
|
console.log("github auth code saved to db");
|
||||||
}
|
self.send('authStage2');
|
||||||
}
|
}, function (error) { //jshint ignore: line
|
||||||
}, function(error) { //jshint ignore: line
|
console.log(error);
|
||||||
console.log(error);
|
self.send('auth');
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
},
|
if (config.userId !== self.session.user.id) {
|
||||||
|
console.log("github auth wrong user ID, switching");
|
||||||
willDestroyElement() {
|
self.set('config.userId', self.session.user.id);
|
||||||
this.destroyTooltips();
|
}
|
||||||
},
|
self.get('sectionService').fetch(page, "checkAuth", self.get('config'))
|
||||||
|
.then(function () {
|
||||||
getOwnerLists() {
|
console.log("github auth code valid");
|
||||||
this.set('busy', true);
|
self.send('authStage2');
|
||||||
|
}, function (error) { //jshint ignore: line
|
||||||
let self = this;
|
console.log(error);
|
||||||
let owners = this.get('owners');
|
self.send('auth'); // require auth if the db token is invalid
|
||||||
let thisOwner = this.get('config.owner');
|
});
|
||||||
let page = this.get('page');
|
}
|
||||||
|
}, function (error) { //jshint ignore: line
|
||||||
if (is.null(thisOwner) || is.undefined(thisOwner)) {
|
console.log(error);
|
||||||
if (owners.length) {
|
});
|
||||||
thisOwner = owners[0];
|
}
|
||||||
this.set('config.owner', thisOwner);
|
},
|
||||||
}
|
|
||||||
} else {
|
willDestroyElement() {
|
||||||
this.set('config.owner', owners.findBy('id', thisOwner.id));
|
this.destroyTooltips();
|
||||||
}
|
},
|
||||||
|
|
||||||
this.set('owner', thisOwner);
|
getOwnerLists() {
|
||||||
|
this.set('busy', true);
|
||||||
this.get('sectionService').fetch(page, "repos", self.get('config'))
|
|
||||||
.then(function(lists) {
|
let self = this;
|
||||||
self.set('busy', false);
|
let owners = this.get('owners');
|
||||||
self.set('repos', lists);
|
let thisOwner = this.get('config.owner');
|
||||||
self.getRepoLists();
|
let page = this.get('page');
|
||||||
}, function(error) { //jshint ignore: line
|
|
||||||
self.set('busy', false);
|
if (is.null(thisOwner) || is.undefined(thisOwner)) {
|
||||||
self.set('authenticated', false);
|
if (owners.length) {
|
||||||
self.showNotification("Unable to fetch repositories");
|
thisOwner = owners[0];
|
||||||
console.log(error);
|
this.set('config.owner', thisOwner);
|
||||||
});
|
}
|
||||||
},
|
} else {
|
||||||
|
this.set('config.owner', owners.findBy('id', thisOwner.id));
|
||||||
getRepoLists() {
|
}
|
||||||
this.set('busy', true);
|
|
||||||
|
this.set('owner', thisOwner);
|
||||||
let repos = this.get('repos');
|
|
||||||
let thisRepo = this.get('config.repo');
|
this.get('sectionService').fetch(page, "repos", self.get('config'))
|
||||||
|
.then(function (lists) {
|
||||||
if (is.null(repos) || is.undefined(repos) || repos.length === 0) {
|
self.set('busy', false);
|
||||||
this.set('noRepos', true);
|
self.set('repos', lists);
|
||||||
return;
|
self.getRepoLists();
|
||||||
}
|
}, function (error) { //jshint ignore: line
|
||||||
|
self.set('busy', false);
|
||||||
this.set('noRepos', false);
|
self.set('authenticated', false);
|
||||||
|
self.showNotification("Unable to fetch repositories");
|
||||||
if (is.null(thisRepo) || is.undefined(thisRepo) || thisRepo.owner !== this.get('config.owner').name) {
|
console.log(error);
|
||||||
if (repos.length) {
|
});
|
||||||
thisRepo = repos[0];
|
},
|
||||||
this.set('config.repo', thisRepo);
|
|
||||||
}
|
getRepoLists() {
|
||||||
} else {
|
this.set('busy', true);
|
||||||
this.set('config.repo', repos.findBy('id', thisRepo.id));
|
|
||||||
}
|
let repos = this.get('repos');
|
||||||
|
let thisRepo = this.get('config.repo');
|
||||||
this.set('repo', thisRepo);
|
|
||||||
|
if (is.null(repos) || is.undefined(repos) || repos.length === 0) {
|
||||||
this.getReportLists();
|
this.set('noRepos', true);
|
||||||
},
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getReportLists() {
|
this.set('noRepos', false);
|
||||||
let reports = [];
|
|
||||||
reports[0] = {
|
if (is.null(thisRepo) || is.undefined(thisRepo) || thisRepo.owner !== this.get('config.owner').name) {
|
||||||
id: "commits_data", // used as method for fetching Go data
|
if (repos.length) {
|
||||||
name: "Commits on a branch"
|
thisRepo = repos[0];
|
||||||
};
|
this.set('config.repo', thisRepo);
|
||||||
reports[1] = {
|
}
|
||||||
id: "issues_data", // used as method for fetching Go data
|
} else {
|
||||||
name: "Issues"
|
this.set('config.repo', repos.findBy('id', thisRepo.id));
|
||||||
};
|
}
|
||||||
|
|
||||||
this.set("reports", reports);
|
this.set('repo', thisRepo);
|
||||||
|
|
||||||
let thisReport = this.get('config.report');
|
this.getReportLists();
|
||||||
|
},
|
||||||
if (is.null(thisReport) || is.undefined(thisReport)) {
|
|
||||||
thisReport = reports[0];
|
getReportLists() {
|
||||||
this.set('config.report', thisReport);
|
let reports = [];
|
||||||
} else {
|
reports[0] = {
|
||||||
this.set('config.report', reports.findBy('id', thisReport.id));
|
id: "commitsData", // used as method for fetching Go data
|
||||||
}
|
name: "Commits on a branch"
|
||||||
|
};
|
||||||
this.set('report', thisReport);
|
reports[1] = {
|
||||||
|
id: "issuesData", // used as method for fetching Go data
|
||||||
this.renderSwitch(thisReport);
|
name: "Issues"
|
||||||
|
};
|
||||||
},
|
|
||||||
|
this.set("reports", reports);
|
||||||
renderSwitch(thisReport) {
|
|
||||||
|
let thisReport = this.get('config.report');
|
||||||
if (is.undefined(this.get('initDateTimePicker'))) {
|
|
||||||
$.datetimepicker.setLocale('en');
|
if (is.null(thisReport) || is.undefined(thisReport)) {
|
||||||
$('#branch-since').datetimepicker();
|
thisReport = reports[0];
|
||||||
this.set('initDateTimePicker', "Done");
|
this.set('config.report', thisReport);
|
||||||
}
|
} else {
|
||||||
|
this.set('config.report', reports.findBy('id', thisReport.id));
|
||||||
let bl = this.get('config.branchLines');
|
}
|
||||||
if (is.undefined(bl) || bl === "" || bl <= 0) {
|
|
||||||
this.set('config.branchLines', "30");
|
this.set('report', thisReport);
|
||||||
}
|
|
||||||
|
this.renderSwitch(thisReport);
|
||||||
this.set('showCommits', false);
|
|
||||||
this.set('showLabels', false);
|
},
|
||||||
switch (thisReport.id) {
|
|
||||||
case 'commits_data':
|
renderSwitch(thisReport) {
|
||||||
this.set('showCommits', true);
|
|
||||||
this.getBranchLists();
|
if (is.undefined(this.get('initDateTimePicker'))) {
|
||||||
break;
|
$.datetimepicker.setLocale('en');
|
||||||
case "issues_data":
|
$('#branch-since').datetimepicker();
|
||||||
this.set('showLabels', true);
|
this.set('initDateTimePicker', "Done");
|
||||||
this.getLabelLists();
|
}
|
||||||
break;
|
|
||||||
}
|
let bl = this.get('config.branchLines');
|
||||||
},
|
if (is.undefined(bl) || bl === "" || bl <= 0) {
|
||||||
|
this.set('config.branchLines', "30");
|
||||||
getBranchLists() {
|
}
|
||||||
this.set('busy', true);
|
|
||||||
|
this.set('showCommits', false);
|
||||||
let self = this;
|
this.set('showLabels', false);
|
||||||
let page = this.get('page');
|
switch (thisReport.id) {
|
||||||
|
case 'commitsData':
|
||||||
this.get('sectionService').fetch(page, "branches", self.get('config'))
|
this.set('showCommits', true);
|
||||||
.then(function(lists) {
|
this.getBranchLists();
|
||||||
let savedLists = self.get('config.lists');
|
break;
|
||||||
if (savedLists === null) {
|
case 'issuesData':
|
||||||
savedLists = [];
|
this.set('showLabels', true);
|
||||||
}
|
this.getLabelLists();
|
||||||
|
break;
|
||||||
if (lists.length > 0) {
|
}
|
||||||
let noIncluded = true;
|
},
|
||||||
|
|
||||||
lists.forEach(function(list) {
|
getBranchLists() {
|
||||||
let included = false;
|
this.set('busy', true);
|
||||||
var saved;
|
|
||||||
if (is.not.undefined(savedLists)) {
|
let self = this;
|
||||||
saved = savedLists.findBy("id", list.id);
|
let page = this.get('page');
|
||||||
}
|
|
||||||
if (is.not.undefined(saved)) {
|
this.get('sectionService').fetch(page, "branches", self.get('config'))
|
||||||
included = saved.included;
|
.then(function (lists) {
|
||||||
noIncluded = false;
|
let savedLists = self.get('config.lists');
|
||||||
}
|
if (savedLists === null) {
|
||||||
list.included = included;
|
savedLists = [];
|
||||||
});
|
}
|
||||||
|
|
||||||
if (noIncluded) {
|
if (lists.length > 0) {
|
||||||
lists[0].included = true; // make the first entry the default
|
let noIncluded = true;
|
||||||
}
|
|
||||||
}
|
lists.forEach(function (list) {
|
||||||
|
let included = false;
|
||||||
self.set('config.lists', lists);
|
var saved;
|
||||||
self.set('busy', false);
|
if (is.not.undefined(savedLists)) {
|
||||||
}, function(error) { //jshint ignore: line
|
saved = savedLists.findBy("id", list.id);
|
||||||
self.set('busy', false);
|
}
|
||||||
self.set('authenticated', false);
|
if (is.not.undefined(saved)) {
|
||||||
self.showNotification("Unable to fetch repository branches");
|
included = saved.included;
|
||||||
console.log(error);
|
noIncluded = false;
|
||||||
});
|
}
|
||||||
},
|
list.included = included;
|
||||||
|
});
|
||||||
getLabelLists() {
|
|
||||||
this.set('busy', true);
|
if (noIncluded) {
|
||||||
|
lists[0].included = true; // make the first entry the default
|
||||||
let self = this;
|
}
|
||||||
let page = this.get('page');
|
}
|
||||||
|
|
||||||
let states = [];
|
self.set('config.lists', lists);
|
||||||
states[0] = {
|
self.set('busy', false);
|
||||||
id: "open",
|
}, function (error) { //jshint ignore: line
|
||||||
name: "Show Open Issues"
|
self.set('busy', false);
|
||||||
};
|
self.set('authenticated', false);
|
||||||
states[1] = {
|
self.showNotification("Unable to fetch repository branches");
|
||||||
id: "closed",
|
console.log(error);
|
||||||
name: "Show Closed Issues"
|
});
|
||||||
};
|
},
|
||||||
states[2] = {
|
|
||||||
id: "all",
|
getLabelLists() {
|
||||||
name: "Show All Issues"
|
this.set('busy', true);
|
||||||
};
|
|
||||||
|
let self = this;
|
||||||
this.set("states", states);
|
let page = this.get('page');
|
||||||
|
|
||||||
let thisState = this.get('config.state');
|
let states = [];
|
||||||
|
states[0] = {
|
||||||
if (is.null(thisState) || is.undefined(thisState)) {
|
id: "open",
|
||||||
thisState = states[0];
|
name: "Show Open Issues"
|
||||||
this.set('config.state', thisState);
|
};
|
||||||
} else {
|
states[1] = {
|
||||||
this.set('config.state', states.findBy('id', thisState.id));
|
id: "closed",
|
||||||
}
|
name: "Show Closed Issues"
|
||||||
|
};
|
||||||
this.set('state', thisState);
|
states[2] = {
|
||||||
|
id: "all",
|
||||||
this.get('sectionService').fetch(page, "labels", self.get('config'))
|
name: "Show All Issues"
|
||||||
.then(function(lists) {
|
};
|
||||||
let savedLists = self.get('config.lists');
|
|
||||||
if (savedLists === null) {
|
this.set("states", states);
|
||||||
savedLists = [];
|
|
||||||
}
|
let thisState = this.get('config.state');
|
||||||
|
|
||||||
if (lists.length > 0) {
|
if (is.null(thisState) || is.undefined(thisState)) {
|
||||||
lists.forEach(function(list) {
|
thisState = states[0];
|
||||||
var saved;
|
this.set('config.state', thisState);
|
||||||
if (is.not.undefined(savedLists)) {
|
} else {
|
||||||
saved = savedLists.findBy("id", list.id);
|
this.set('config.state', states.findBy('id', thisState.id));
|
||||||
}
|
}
|
||||||
let included = false;
|
|
||||||
if (is.not.undefined(saved)) {
|
this.set('state', thisState);
|
||||||
included = saved.included;
|
|
||||||
}
|
this.get('sectionService').fetch(page, "labels", self.get('config'))
|
||||||
list.included = included;
|
.then(function (lists) {
|
||||||
});
|
let savedLists = self.get('config.lists');
|
||||||
}
|
if (savedLists === null) {
|
||||||
|
savedLists = [];
|
||||||
self.set('config.lists', lists);
|
}
|
||||||
self.set('busy', false);
|
|
||||||
}, function(error) { //jshint ignore: line
|
if (lists.length > 0) {
|
||||||
self.set('busy', false);
|
lists.forEach(function (list) {
|
||||||
self.set('authenticated', false);
|
var saved;
|
||||||
self.showNotification("Unable to fetch repository labels");
|
if (is.not.undefined(savedLists)) {
|
||||||
console.log(error);
|
saved = savedLists.findBy("id", list.id);
|
||||||
});
|
}
|
||||||
},
|
let included = false;
|
||||||
|
if (is.not.undefined(saved)) {
|
||||||
actions: {
|
included = saved.included;
|
||||||
isDirty() {
|
}
|
||||||
return this.get('isDirty');
|
list.included = included;
|
||||||
},
|
});
|
||||||
|
}
|
||||||
onListCheckbox(id) {
|
|
||||||
let lists = this.get('config.lists');
|
self.set('config.lists', lists);
|
||||||
let list = lists.findBy('id', id);
|
self.set('busy', false);
|
||||||
|
}, function (error) { //jshint ignore: line
|
||||||
// restore the list of branches to the default state
|
self.set('busy', false);
|
||||||
lists.forEach(function(lst) {
|
self.set('authenticated', false);
|
||||||
Ember.set(lst, 'included', false);
|
self.showNotification("Unable to fetch repository labels");
|
||||||
});
|
console.log(error);
|
||||||
|
});
|
||||||
if (list !== null) {
|
},
|
||||||
Ember.set(list, 'included', !list.included);
|
|
||||||
}
|
actions: {
|
||||||
},
|
isDirty() {
|
||||||
|
return this.get('isDirty');
|
||||||
onLabelCheckbox(id) {
|
},
|
||||||
let lists = this.get('config.lists');
|
|
||||||
let list = lists.findBy('id', id);
|
onListCheckbox(id) {
|
||||||
|
let lists = this.get('config.lists');
|
||||||
if (list !== null) {
|
let list = lists.findBy('id', id);
|
||||||
Ember.set(list, 'included', !list.included);
|
|
||||||
}
|
// restore the list of branches to the default state
|
||||||
},
|
lists.forEach(function (lst) {
|
||||||
|
Ember.set(lst, 'included', false);
|
||||||
|
});
|
||||||
authStage2() {
|
|
||||||
let self = this;
|
if (list !== null) {
|
||||||
self.set('authenticated', true);
|
Ember.set(list, 'included', !list.included);
|
||||||
self.set('busy', true);
|
}
|
||||||
let page = this.get('page');
|
},
|
||||||
|
|
||||||
self.get('sectionService').fetch(page, "owners", self.get('config'))
|
onLabelCheckbox(id) {
|
||||||
.then(function(owners) {
|
let lists = this.get('config.lists');
|
||||||
self.set('busy', false);
|
let list = lists.findBy('id', id);
|
||||||
self.set('owners', owners);
|
|
||||||
self.getOwnerLists();
|
if (list !== null) {
|
||||||
}, function(error) { //jshint ignore: line
|
Ember.set(list, 'included', !list.included);
|
||||||
self.set('busy', false);
|
}
|
||||||
self.set('authenticated', false);
|
},
|
||||||
self.showNotification("Unable to fetch owners");
|
|
||||||
console.log(error);
|
authStage2() {
|
||||||
});
|
let self = this;
|
||||||
|
self.set('config.userId', this.session.user.id);
|
||||||
},
|
self.set('authenticated', true);
|
||||||
|
self.set('busy', true);
|
||||||
auth() {
|
let page = this.get('page');
|
||||||
|
|
||||||
let self = this;
|
self.get('sectionService').fetch(page, "owners", self.get('config'))
|
||||||
self.set('busy', true);
|
.then(function (owners) {
|
||||||
self.set('authenticated', false);
|
self.set('busy', false);
|
||||||
let target = "https://github.com/login/oauth/authorize?client_id=" + self.get('config.clientId') +
|
self.set('owners', owners);
|
||||||
"&scope=repo&redirect_uri=" + encodeURIComponent(self.get('config.callbackUrl')) +
|
self.getOwnerLists();
|
||||||
"&state=" + encodeURIComponent(window.location.href);
|
}, function (error) { //jshint ignore: line
|
||||||
window.location.href = target;
|
self.set('busy', false);
|
||||||
|
self.set('authenticated', false);
|
||||||
},
|
self.showNotification("Unable to fetch owners");
|
||||||
|
console.log(error);
|
||||||
onOwnerChange(thisOwner) {
|
});
|
||||||
this.set('isDirty', true);
|
|
||||||
this.set('config.owner', thisOwner);
|
},
|
||||||
this.set('config.repos', []);
|
|
||||||
this.set('config.lists', []);
|
auth() {
|
||||||
this.getOwnerLists();
|
let self = this;
|
||||||
},
|
self.set('busy', true);
|
||||||
|
self.set('authenticated', false);
|
||||||
onRepoChange(thisRepo) {
|
let target = "https://github.com/login/oauth/authorize?client_id=" + self.get('config.clientId') +
|
||||||
this.set('isDirty', true);
|
"&scope=repo&redirect_uri=" + encodeURIComponent(self.get('config.callbackUrl')) +
|
||||||
this.set('config.repo', thisRepo);
|
"&state=" + encodeURIComponent(window.location.href);
|
||||||
this.set('config.lists', []);
|
window.location.href = target;
|
||||||
this.getRepoLists();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onReportChange(thisReport) {
|
onOwnerChange(thisOwner) {
|
||||||
this.set('isDirty', true);
|
this.set('isDirty', true);
|
||||||
this.set('config.report', thisReport);
|
this.set('config.owner', thisOwner);
|
||||||
this.getReportLists();
|
this.set('config.repos', []);
|
||||||
},
|
this.set('config.lists', []);
|
||||||
|
this.getOwnerLists();
|
||||||
onStateChange(thisState) {
|
},
|
||||||
this.set('config.state', thisState);
|
|
||||||
},
|
onRepoChange(thisRepo) {
|
||||||
|
this.set('isDirty', true);
|
||||||
|
this.set('config.repo', thisRepo);
|
||||||
onCancel() {
|
this.set('config.lists', []);
|
||||||
this.attrs.onCancel();
|
this.getRepoLists();
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction(title) {
|
onReportChange(thisReport) {
|
||||||
this.set('busy', true);
|
this.set('isDirty', true);
|
||||||
|
this.set('config.report', thisReport);
|
||||||
let thisLines = this.get('config.branchLines');
|
this.getReportLists();
|
||||||
if (is.undefined(thisLines) || thisLines === "") {
|
},
|
||||||
this.set('config.branchLines', 30);
|
|
||||||
} else if (thisLines < 1) {
|
onStateChange(thisState) {
|
||||||
this.set('config.branchLines', 1);
|
this.set('config.state', thisState);
|
||||||
} else if (thisLines > 100) {
|
},
|
||||||
this.set('config.branchLines', 100);
|
|
||||||
}
|
onCancel() {
|
||||||
|
this.attrs.onCancel();
|
||||||
let self = this;
|
},
|
||||||
let page = this.get('page');
|
|
||||||
let meta = this.get('meta');
|
onAction(title) {
|
||||||
page.set('title', title);
|
this.set('busy', true);
|
||||||
meta.set('rawBody', '');
|
|
||||||
meta.set('config', JSON.stringify(this.get('config')));
|
let thisLines = this.get('config.branchLines');
|
||||||
meta.set('externalSource', true);
|
if (is.undefined(thisLines) || thisLines === "") {
|
||||||
|
this.set('config.branchLines', 30);
|
||||||
let thisReport = this.get('config.report');
|
} else if (thisLines < 1) {
|
||||||
this.get('sectionService').fetch(page, thisReport.id, this.get('config'))
|
this.set('config.branchLines', 1);
|
||||||
.then(function(response) {
|
} else if (thisLines > 100) {
|
||||||
meta.set('rawBody', JSON.stringify(response));
|
this.set('config.branchLines', 100);
|
||||||
self.set('busy', false);
|
}
|
||||||
self.attrs.onAction(page, meta);
|
|
||||||
}, function(reason) { //jshint ignore: line
|
let self = this;
|
||||||
self.set('busy', false);
|
let page = this.get('page');
|
||||||
self.attrs.onAction(page, meta);
|
let meta = this.get('meta');
|
||||||
});
|
page.set('title', title);
|
||||||
}
|
meta.set('rawBody', '');
|
||||||
}
|
meta.set('config', JSON.stringify(this.get('config')));
|
||||||
|
meta.set('externalSource', true);
|
||||||
|
|
||||||
|
let thisReport = this.get('config.report');
|
||||||
|
this.get('sectionService').fetch(page, thisReport.id, this.get('config'))
|
||||||
|
.then(function (response) {
|
||||||
|
meta.set('rawBody', JSON.stringify(response));
|
||||||
|
self.set('busy', false);
|
||||||
|
self.attrs.onAction(page, meta);
|
||||||
|
}, function (reason) { //jshint ignore: line
|
||||||
|
self.set('busy', false);
|
||||||
|
self.attrs.onAction(page, meta);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
|
@ -16,40 +16,40 @@ import SectionMixin from '../../../mixins/section';
|
||||||
import netUtil from '../../../utils/net';
|
import netUtil from '../../../utils/net';
|
||||||
|
|
||||||
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
|
export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin, {
|
||||||
sectionService: Ember.inject.service('section'),
|
sectionService: Ember.inject.service('section'),
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
waiting: false,
|
waiting: false,
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
config: {},
|
config: {},
|
||||||
items: {},
|
items: {},
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
let config = {};
|
let config = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config = JSON.parse(this.get('meta.config'));
|
config = JSON.parse(this.get('meta.config'));
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
if (is.empty(config)) {
|
if (is.empty(config)) {
|
||||||
config = {
|
config = {
|
||||||
APIToken: "",
|
APIToken: "",
|
||||||
query: "",
|
query: "",
|
||||||
max: 10,
|
max: 10,
|
||||||
group: null,
|
group: null,
|
||||||
system: null
|
system: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('config', config);
|
this.set('config', config);
|
||||||
|
|
||||||
if (this.get('config.APIToken').length > 0) {
|
if (this.get('config.APIToken').length > 0) {
|
||||||
this.send('auth');
|
this.send('auth');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this.destroyTooltips();
|
this.destroyTooltips();
|
||||||
},
|
},
|
||||||
|
|
||||||
displayError(reason) {
|
displayError(reason) {
|
||||||
if (netUtil.isAjaxAccessError(reason)) {
|
if (netUtil.isAjaxAccessError(reason)) {
|
||||||
|
@ -59,98 +59,102 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
isDirty() {
|
isDirty() {
|
||||||
return this.get('isDirty');
|
return this.get('isDirty');
|
||||||
},
|
},
|
||||||
|
|
||||||
auth() {
|
auth() {
|
||||||
|
console.log(this.get('config'));
|
||||||
// missing data?
|
// missing data?
|
||||||
this.set('config.APIToken', this.get('config.APIToken').trim());
|
this.set('config.APIToken', this.get('config.APIToken').trim());
|
||||||
|
|
||||||
if (is.empty(this.get('config.APIToken'))) {
|
if (is.empty(this.get('config.APIToken'))) {
|
||||||
$("#papertrail-apitoken").addClass("error").focus();
|
$("#papertrail-apitoken").addClass("error").focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let config = this.get('config');
|
let config = this.get('config');
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
this.set('waiting', true);
|
this.set('waiting', true);
|
||||||
|
|
||||||
this.get('sectionService').fetch(page, "auth", config)
|
this.get('sectionService').fetch(page, "auth", config)
|
||||||
.then(function(response) {
|
.then(function (response) {
|
||||||
self.set('authenticated', true);
|
self.set('authenticated', true);
|
||||||
self.set('items', response);
|
self.set('items', response);
|
||||||
|
self.set('config.APIToken', '********'); // reset the api token once it has been sent to the host
|
||||||
|
|
||||||
self.get('sectionService').fetch(page, "options", config)
|
self.get('sectionService').fetch(page, "options", config)
|
||||||
.then(function(response) {
|
.then(function (response) {
|
||||||
self.set('options', response);
|
self.set('options', response);
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
|
|
||||||
let options = self.get('options');
|
let options = self.get('options');
|
||||||
let group = _.findWhere(options.groups, {id: config.group.id});
|
let group = _.findWhere(options.groups, { id: config.group.id });
|
||||||
if (is.not.undefined(group)) {
|
if (is.not.undefined(group)) {
|
||||||
Ember.set(config, 'group', group);
|
Ember.set(config, 'group', group);
|
||||||
}
|
}
|
||||||
}, function(reason) { //jshint ignore: line
|
}, function (reason) { //jshint ignore: line
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
|
self.displayError(reason);
|
||||||
|
});
|
||||||
|
}, function (reason) { //jshint ignore: line
|
||||||
|
self.set('authenticated', false);
|
||||||
|
self.set('waiting', false);
|
||||||
|
self.set('config.APIToken', ''); // clear the api token
|
||||||
self.displayError(reason);
|
self.displayError(reason);
|
||||||
});
|
$("#papertrail-apitoken").addClass("error").focus();
|
||||||
}, function(reason) { //jshint ignore: line
|
});
|
||||||
self.set('authenticated', false);
|
},
|
||||||
self.set('waiting', false);
|
|
||||||
self.displayError(reason);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onGroupsChange(group) {
|
onGroupsChange(group) {
|
||||||
let config = this.get('config');
|
let config = this.get('config');
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let self = this;
|
let self = this;
|
||||||
this.set('isDirty', true);
|
this.set('isDirty', true);
|
||||||
this.set('config.group', group);
|
this.set('config.group', group);
|
||||||
this.set('waiting', true);
|
this.set('waiting', true);
|
||||||
|
|
||||||
this.get('sectionService').fetch(page, "auth", config)
|
this.get('sectionService').fetch(page, "auth", config)
|
||||||
.then(function(response) {
|
.then(function (response) {
|
||||||
|
self.set('waiting', false);
|
||||||
|
self.set('items', response);
|
||||||
|
}, function (reason) { //jshint ignore: line
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
self.set('items', response);
|
|
||||||
}, function(reason) { //jshint ignore: line
|
|
||||||
self.set('waiting', false);
|
|
||||||
self.displayError(reason);
|
self.displayError(reason);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onSystemsChange(system) {
|
onSystemsChange(system) {
|
||||||
let config = this.get('config');
|
let config = this.get('config');
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let self = this;
|
let self = this;
|
||||||
this.set('isDirty', true);
|
this.set('isDirty', true);
|
||||||
this.set('config.system', system);
|
this.set('config.system', system);
|
||||||
this.set('waiting', true);
|
this.set('waiting', true);
|
||||||
|
|
||||||
this.get('sectionService').fetch(page, "auth", config)
|
this.get('sectionService').fetch(page, "auth", config)
|
||||||
.then(function(response) {
|
.then(function (response) {
|
||||||
|
self.set('waiting', false);
|
||||||
|
self.set('items', response);
|
||||||
|
}, function (reason) { //jshint ignore: line
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
self.set('items', response);
|
|
||||||
}, function(reason) { //jshint ignore: line
|
|
||||||
self.set('waiting', false);
|
|
||||||
self.displayError(reason);
|
self.displayError(reason);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
this.attrs.onCancel();
|
this.attrs.onCancel();
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction(title) {
|
onAction(title) {
|
||||||
let self = this;
|
let self = this;
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let meta = this.get('meta');
|
let meta = this.get('meta');
|
||||||
page.set('title', title);
|
page.set('title', title);
|
||||||
meta.set('externalSource', true);
|
meta.set('externalSource', true);
|
||||||
|
|
||||||
let config = this.get('config');
|
let config = this.get('config');
|
||||||
let max = 10;
|
let max = 10;
|
||||||
|
@ -161,25 +165,25 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin,
|
||||||
Ember.set(config, 'max', max);
|
Ember.set(config, 'max', max);
|
||||||
this.set('waiting', true);
|
this.set('waiting', true);
|
||||||
|
|
||||||
this.get('sectionService').fetch(page, "auth", this.get('config'))
|
this.get('sectionService').fetch(page, "auth", this.get('config'))
|
||||||
.then(function(response) {
|
.then(function (response) {
|
||||||
self.set('items', response);
|
self.set('items', response);
|
||||||
let items = self.get('items');
|
let items = self.get('items');
|
||||||
|
|
||||||
if (items.events.length > max) {
|
if (items.events.length > max) {
|
||||||
items.events = items.events.slice(0, max);
|
items.events = items.events.slice(0, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta.set('config', JSON.stringify(config));
|
meta.set('config', JSON.stringify(config));
|
||||||
meta.set('rawBody', JSON.stringify(items));
|
meta.set('rawBody', JSON.stringify(items));
|
||||||
|
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
self.attrs.onAction(page, meta);
|
self.attrs.onAction(page, meta);
|
||||||
}, function(reason) { //jshint ignore: line
|
}, function (reason) { //jshint ignore: line
|
||||||
self.set('authenticated', false);
|
self.set('authenticated', false);
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
self.showNotification(`Something went wrong, try again!`);
|
self.showNotification(`Something went wrong, try again!`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -14,61 +14,65 @@ import netUtil from '../utils/net';
|
||||||
import config from '../config/environment';
|
import config from '../config/environment';
|
||||||
|
|
||||||
export default Ember.Service.extend({
|
export default Ember.Service.extend({
|
||||||
sessionService: Ember.inject.service('session'),
|
sessionService: Ember.inject.service('session'),
|
||||||
ready: false,
|
ready: false,
|
||||||
enabled: config.APP.auditEnabled,
|
enabled: config.APP.auditEnabled,
|
||||||
appId: config.APP.intercomKey,
|
appId: config.APP.intercomKey,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.start();
|
this.start();
|
||||||
},
|
},
|
||||||
|
|
||||||
record(id) {
|
record(id) {
|
||||||
if (!this.get('enabled') || is.empty(this.get('appId'))) {
|
if (!this.get('enabled') || this.get('appId').length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.get('ready')) {
|
if (!this.get('ready')) {
|
||||||
this.start();
|
this.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Intercom('trackEvent', id); //jshint ignore: line
|
Intercom('trackEvent', id); //jshint ignore: line
|
||||||
Intercom('update'); //jshint ignore: line
|
Intercom('update'); //jshint ignore: line
|
||||||
},
|
},
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
Intercom('shutdown'); //jshint ignore: line
|
if (!this.get('enabled') || this.get('appId').length === 0) {
|
||||||
},
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
start() {
|
Intercom('shutdown'); //jshint ignore: line
|
||||||
let session = this.get('sessionService');
|
},
|
||||||
|
|
||||||
if (this.get('appId') === "" || !this.get('enabled') || !session.authenticated || this.get('ready')) {
|
start() {
|
||||||
return;
|
let session = this.get('sessionService');
|
||||||
}
|
|
||||||
|
|
||||||
this.set('ready', true);
|
if (this.get('appId') === "" || !this.get('enabled') || !session.authenticated || this.get('ready')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window.intercomSettings = {
|
this.set('ready', true);
|
||||||
app_id: this.get('appId'),
|
|
||||||
name: session.user.firstname + " " + session.user.lastname,
|
|
||||||
email: session.user.email,
|
|
||||||
user_id: session.user.id,
|
|
||||||
"administrator": session.user.admin,
|
|
||||||
company: {
|
|
||||||
id: session.get('appMeta.orgId'),
|
|
||||||
name: session.get('appMeta.title').string,
|
|
||||||
"domain": netUtil.getSubdomain(),
|
|
||||||
"version": session.get('appMeta.version')
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!session.get('isMobile')) {
|
window.intercomSettings = {
|
||||||
window.intercomSettings.widget = {
|
app_id: this.get('appId'),
|
||||||
activator: "#IntercomDefaultWidget"
|
name: session.user.firstname + " " + session.user.lastname,
|
||||||
};
|
email: session.user.email,
|
||||||
}
|
user_id: session.user.id,
|
||||||
|
"administrator": session.user.admin,
|
||||||
|
company: {
|
||||||
|
id: session.get('appMeta.orgId'),
|
||||||
|
name: session.get('appMeta.title').string,
|
||||||
|
"domain": netUtil.getSubdomain(),
|
||||||
|
"version": session.get('appMeta.version')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
window.Intercom('boot', window.intercomSettings);
|
if (!session.get('isMobile')) {
|
||||||
},
|
window.intercomSettings.widget = {
|
||||||
|
activator: "#IntercomDefaultWidget"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Intercom('boot', window.intercomSettings);
|
||||||
|
},
|
||||||
});
|
});
|
|
@ -4,7 +4,11 @@
|
||||||
<div class="input-form">
|
<div class="input-form">
|
||||||
<form {{action 'auth' on="submit"}}>
|
<form {{action 'auth' on="submit"}}>
|
||||||
<div class="heading">
|
<div class="heading">
|
||||||
<div class="title">Papertrail Authentication</div>
|
<div class="title">Papertrail Authentication
|
||||||
|
{{#if authenticated}}
|
||||||
|
Complete
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
<div class="tip">Provide your Papertrail API token</div>
|
<div class="tip">Provide your Papertrail API token</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-control">
|
<div class="input-control">
|
||||||
|
@ -12,7 +16,11 @@
|
||||||
<div class="tip">API Token (from your profile)</div>
|
<div class="tip">API Token (from your profile)</div>
|
||||||
{{focus-input id="papertrail-apitoken" type="password" value=config.APIToken readonly=isReadonly}}
|
{{focus-input id="papertrail-apitoken" type="password" value=config.APIToken readonly=isReadonly}}
|
||||||
</div>
|
</div>
|
||||||
<div class="regular-button button-blue" {{ action 'auth' }}>Authenticate</div>
|
{{#if authenticated}}
|
||||||
|
<div class="regular-button button-blue" {{ action 'auth' }}>Re-Authenticate</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="regular-button button-blue" {{ action 'auth' }}>Authenticate</div>
|
||||||
|
{{/if}}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,37 +10,37 @@
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
function getSubdomain() {
|
function getSubdomain() {
|
||||||
if (is.ipv4(window.location.host)) {
|
if (is.ipv4(window.location.host)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
let domain = "";
|
let domain = "";
|
||||||
let parts = window.location.host.split(".");
|
let parts = window.location.host.split(".");
|
||||||
|
|
||||||
if (parts.length > 1) {
|
if (parts.length > 1) {
|
||||||
domain = parts[0].toLowerCase();
|
domain = parts[0].toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAppUrl(domain) {
|
function getAppUrl(domain) {
|
||||||
let parts = window.location.host.split(".");
|
let parts = window.location.host.split(".");
|
||||||
parts.removeAt(0);
|
parts.removeAt(0);
|
||||||
|
|
||||||
let leftOvers = parts.join(".");
|
let leftOvers = parts.join(".");
|
||||||
|
|
||||||
if (is.empty(domain)) {
|
if (is.empty(domain)) {
|
||||||
domain = "";
|
domain = "";
|
||||||
} else {
|
} else {
|
||||||
domain = domain + ".";
|
domain = domain + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
return window.location.protocol + "//" + domain + leftOvers;
|
return window.location.protocol + "//" + domain + leftOvers;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAjaxAccessError(reason) {
|
function isAjaxAccessError(reason) {
|
||||||
if (typeof reason === "undefined") {
|
if (typeof reason === "undefined" || typeof reason.errors === "undefined") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ function isAjaxAccessError(reason) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getSubdomain,
|
getSubdomain,
|
||||||
getAppUrl,
|
getAppUrl,
|
||||||
isAjaxAccessError,
|
isAjaxAccessError,
|
||||||
};
|
};
|
|
@ -79,6 +79,8 @@ func AddDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
model.Meta.PageID = pageID
|
model.Meta.PageID = pageID
|
||||||
model.Page.SetDefaults()
|
model.Page.SetDefaults()
|
||||||
model.Meta.SetDefaults()
|
model.Meta.SetDefaults()
|
||||||
|
model.Meta.OrgID = p.Context.OrgID
|
||||||
|
model.Meta.UserID = p.Context.UserID
|
||||||
// page.Title = template.HTMLEscapeString(page.Title)
|
// page.Title = template.HTMLEscapeString(page.Title)
|
||||||
|
|
||||||
tx, err := request.Db.Beginx()
|
tx, err := request.Db.Beginx()
|
||||||
|
@ -90,7 +92,8 @@ func AddDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
p.Context.Transaction = tx
|
p.Context.Transaction = tx
|
||||||
|
|
||||||
output, ok := provider.Render(model.Page.ContentType, model.Meta.Config, model.Meta.RawBody)
|
output, ok := provider.Render(model.Page.ContentType,
|
||||||
|
provider.NewContext(model.Meta.OrgID, model.Meta.UserID), model.Meta.Config, model.Meta.RawBody)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.ErrorString("provider.Render could not find: " + model.Page.ContentType)
|
log.ErrorString("provider.Render could not find: " + model.Page.ContentType)
|
||||||
}
|
}
|
||||||
|
@ -374,7 +377,7 @@ func DeleteDocumentPages(w http.ResponseWriter, r *http.Request) {
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateDocumentPage will persiste changed page and note the fact
|
// UpdateDocumentPage will persist changed page and note the fact
|
||||||
// that this is a new revision. If the page is the first in a document
|
// that this is a new revision. If the page is the first in a document
|
||||||
// then the corresponding document title will also be changed.
|
// then the corresponding document title will also be changed.
|
||||||
func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) {
|
func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -432,7 +435,15 @@ func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
model.Page.SetDefaults()
|
model.Page.SetDefaults()
|
||||||
model.Meta.SetDefaults()
|
model.Meta.SetDefaults()
|
||||||
|
|
||||||
output, ok := provider.Render(model.Page.ContentType, model.Meta.Config, model.Meta.RawBody)
|
oldPageMeta, err := p.GetPageMeta(pageID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("unable to fetch old pagemeta record", err)
|
||||||
|
writeBadRequestError(w, method, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
output, ok := provider.Render(model.Page.ContentType, provider.NewContext(model.Meta.OrgID, oldPageMeta.UserID), model.Meta.Config, model.Meta.RawBody)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.ErrorString("provider.Render could not find: " + model.Page.ContentType)
|
log.ErrorString("provider.Render could not find: " + model.Page.ContentType)
|
||||||
}
|
}
|
||||||
|
@ -452,7 +463,7 @@ func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.UpdatePageMeta(model.Meta)
|
err = p.UpdatePageMeta(model.Meta, true) // change the UserID to the current one
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ func RunSectionCommand(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !provider.Command(sectionName, w, r) {
|
if !provider.Command(sectionName, provider.NewContext(p.Context.OrgID, p.Context.UserID), w, r) {
|
||||||
log.ErrorString("Unable to run provider.Command() for: " + sectionName)
|
log.ErrorString("Unable to run provider.Command() for: " + sectionName)
|
||||||
writeNotFoundError(w, "RunSectionCommand", sectionName)
|
writeNotFoundError(w, "RunSectionCommand", sectionName)
|
||||||
}
|
}
|
||||||
|
@ -125,14 +125,16 @@ func RefreshSections(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcontext := provider.NewContext(pm.OrgID, pm.UserID)
|
||||||
|
|
||||||
// Ask for data refresh
|
// Ask for data refresh
|
||||||
data, ok := provider.Refresh(page.ContentType, pm.Config, pm.RawBody)
|
data, ok := provider.Refresh(page.ContentType, pcontext, pm.Config, pm.RawBody)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.ErrorString("provider.Refresh could not find: " + page.ContentType)
|
log.ErrorString("provider.Refresh could not find: " + page.ContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render again
|
// Render again
|
||||||
body, ok := provider.Render(page.ContentType, pm.Config, data)
|
body, ok := provider.Render(page.ContentType, pcontext, pm.Config, data)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.ErrorString("provider.Render could not find: " + page.ContentType)
|
log.ErrorString("provider.Render could not find: " + page.ContentType)
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,7 @@ func RefreshSections(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.UpdatePageMeta(pm)
|
err = p.UpdatePageMeta(pm, false) // do not change the UserID on this PageMeta
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeGeneralSQLError(w, method, err)
|
writeGeneralSQLError(w, method, err)
|
||||||
|
|
|
@ -204,6 +204,7 @@ type PageMeta struct {
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
Revised time.Time `json:"revised"`
|
Revised time.Time `json:"revised"`
|
||||||
OrgID string `json:"orgId"`
|
OrgID string `json:"orgId"`
|
||||||
|
UserID string `json:"userId"`
|
||||||
DocumentID string `json:"documentId"`
|
DocumentID string `json:"documentId"`
|
||||||
PageID string `json:"pageId"`
|
PageID string `json:"pageId"`
|
||||||
RawBody string `json:"rawBody"` // a blob of data
|
RawBody string `json:"rawBody"` // a blob of data
|
||||||
|
|
|
@ -13,6 +13,7 @@ package request
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/documize/community/wordsmith/utility"
|
"github.com/documize/community/wordsmith/utility"
|
||||||
)
|
)
|
||||||
|
@ -65,3 +66,64 @@ func ConfigString(area, path string) (ret string) {
|
||||||
//fmt.Println("DEBUG ConfigString " + sql + " => " + ret)
|
//fmt.Println("DEBUG ConfigString " + sql + " => " + ret)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserConfigGetJSON fetches a configuration JSON element from the userconfig table for a given orgid/userid combination.
|
||||||
|
// Errors return the empty string. A blank path returns the whole JSON object, as JSON.
|
||||||
|
func UserConfigGetJSON(orgid, userid, area, path string) (ret string) {
|
||||||
|
if Db == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if path != "" {
|
||||||
|
path = "." + path
|
||||||
|
}
|
||||||
|
sql := "SELECT JSON_EXTRACT(`config`,'$" + path + "') FROM `userconfig` WHERE `key` = '" + area +
|
||||||
|
"' AND `orgid` = '" + orgid + "' AND `userid` = '" + userid + "';"
|
||||||
|
|
||||||
|
stmt, err := Db.Preparex(sql)
|
||||||
|
if err != nil {
|
||||||
|
//fmt.Printf("DEBUG: Unable to prepare select SQL for ConfigString: %s -- error: %v\n", sql, err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer utility.Close(stmt)
|
||||||
|
|
||||||
|
var item = make([]uint8, 0)
|
||||||
|
|
||||||
|
err = stmt.Get(&item)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
//fmt.Printf("DEBUG: Unable to prepare execute SQL for ConfigString: %s -- error: %v\n", sql, err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(item) > 1 {
|
||||||
|
q := []byte(`"`)
|
||||||
|
ret = string(bytes.TrimPrefix(bytes.TrimSuffix(item, q), q))
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Println("DEBUG UserConfigString " + sql + " => " + ret)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserConfigSetJSON writes a configuration JSON element to the userconfig table for the current user.
|
||||||
|
func UserConfigSetJSON(orgid, userid, area, json string) error {
|
||||||
|
if Db == nil {
|
||||||
|
return errors.New("no database")
|
||||||
|
}
|
||||||
|
if area == "" {
|
||||||
|
return errors.New("no area")
|
||||||
|
}
|
||||||
|
sql := "INSERT INTO `userconfig` (`orgid`,`userid`,`key`,`config`) " +
|
||||||
|
"VALUES ('" + orgid + "','" + userid + "','" + area + "','" + json +
|
||||||
|
"') ON DUPLICATE KEY UPDATE `config`='" + json + "';"
|
||||||
|
|
||||||
|
stmt, err := Db.Preparex(sql)
|
||||||
|
if err != nil {
|
||||||
|
//fmt.Printf("DEBUG: Unable to prepare select SQL for UserConfigSetJSON: %s -- error: %v\n", sql, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer utility.Close(stmt)
|
||||||
|
|
||||||
|
_,err= stmt.Exec()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ func (p *Persister) AddPage(model models.PageModel) (err error) {
|
||||||
model.Page.SetDefaults()
|
model.Page.SetDefaults()
|
||||||
|
|
||||||
model.Meta.OrgID = p.Context.OrgID
|
model.Meta.OrgID = p.Context.OrgID
|
||||||
|
model.Meta.UserID = p.Context.UserID
|
||||||
model.Meta.DocumentID = model.Page.DocumentID
|
model.Meta.DocumentID = model.Page.DocumentID
|
||||||
model.Meta.Created = time.Now().UTC()
|
model.Meta.Created = time.Now().UTC()
|
||||||
model.Meta.Revised = time.Now().UTC()
|
model.Meta.Revised = time.Now().UTC()
|
||||||
|
@ -65,7 +66,7 @@ func (p *Persister) AddPage(model models.PageModel) (err error) {
|
||||||
|
|
||||||
err = searches.Add(&databaseRequest{OrgID: p.Context.OrgID}, model.Page, model.Page.RefID)
|
err = searches.Add(&databaseRequest{OrgID: p.Context.OrgID}, model.Page, model.Page.RefID)
|
||||||
|
|
||||||
stmt2, err := p.Context.Transaction.Preparex("INSERT INTO pagemeta (pageid, orgid, documentid, rawbody, config, externalsource, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
|
stmt2, err := p.Context.Transaction.Preparex("INSERT INTO pagemeta (pageid, orgid, userid, documentid, rawbody, config, externalsource, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||||
defer utility.Close(stmt2)
|
defer utility.Close(stmt2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -73,7 +74,7 @@ func (p *Persister) AddPage(model models.PageModel) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmt2.Exec(model.Meta.PageID, model.Meta.OrgID, model.Meta.DocumentID, model.Meta.RawBody, model.Meta.Config, model.Meta.ExternalSource, model.Meta.Created, model.Meta.Revised)
|
_, err = stmt2.Exec(model.Meta.PageID, model.Meta.OrgID, model.Meta.UserID, model.Meta.DocumentID, model.Meta.RawBody, model.Meta.Config, model.Meta.ExternalSource, model.Meta.Created, model.Meta.Revised)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to execute insert for page meta", err)
|
log.Error("Unable to execute insert for page meta", err)
|
||||||
|
@ -291,12 +292,15 @@ func (p *Persister) UpdatePage(page entity.Page, refID, userID string, skipRevis
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePageMeta persists meta information associated with a document page.
|
// UpdatePageMeta persists meta information associated with a document page.
|
||||||
func (p *Persister) UpdatePageMeta(meta entity.PageMeta) (err error) {
|
func (p *Persister) UpdatePageMeta(meta entity.PageMeta,updateUserID bool) (err error) {
|
||||||
err = nil
|
err = nil
|
||||||
meta.Revised = time.Now().UTC()
|
meta.Revised = time.Now().UTC()
|
||||||
|
if updateUserID {
|
||||||
|
meta.UserID=p.Context.UserID
|
||||||
|
}
|
||||||
|
|
||||||
var stmt *sqlx.NamedStmt
|
var stmt *sqlx.NamedStmt
|
||||||
stmt, err = p.Context.Transaction.PrepareNamed("UPDATE pagemeta SET documentid=:documentid, rawbody=:rawbody, config=:config, externalsource=:externalsource, revised=:revised WHERE orgid=:orgid AND pageid=:pageid")
|
stmt, err = p.Context.Transaction.PrepareNamed("UPDATE pagemeta SET userid=:userid, documentid=:documentid, rawbody=:rawbody, config=:config, externalsource=:externalsource, revised=:revised WHERE orgid=:orgid AND pageid=:pageid")
|
||||||
defer utility.Close(stmt)
|
defer utility.Close(stmt)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -383,7 +387,7 @@ func (p *Persister) DeletePage(documentID, pageID string) (rows int64, err error
|
||||||
func (p *Persister) GetPageMeta(pageID string) (meta entity.PageMeta, err error) {
|
func (p *Persister) GetPageMeta(pageID string) (meta entity.PageMeta, err error) {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
stmt, err := Db.Preparex("SELECT id, pageid, orgid, documentid, rawbody, coalesce(config,JSON_UNQUOTE('{}')) as config, externalsource, created, revised FROM pagemeta WHERE orgid=? AND pageid=?")
|
stmt, err := Db.Preparex("SELECT id, pageid, orgid, userid, documentid, rawbody, coalesce(config,JSON_UNQUOTE('{}')) as config, externalsource, created, revised FROM pagemeta WHERE orgid=? AND pageid=?")
|
||||||
defer utility.Close(stmt)
|
defer utility.Close(stmt)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -409,7 +413,7 @@ func (p *Persister) GetDocumentPageMeta(documentID string, externalSourceOnly bo
|
||||||
filter = " AND externalsource=1"
|
filter = " AND externalsource=1"
|
||||||
}
|
}
|
||||||
|
|
||||||
err = Db.Select(&meta, "SELECT id, pageid, orgid, documentid, rawbody, coalesce(config,JSON_UNQUOTE('{}')) as config, externalsource, created, revised FROM pagemeta WHERE orgid=? AND documentid=?"+filter, p.Context.OrgID, documentID)
|
err = Db.Select(&meta, "SELECT id, pageid, orgid, userid, documentid, rawbody, coalesce(config,JSON_UNQUOTE('{}')) as config, externalsource, created, revised FROM pagemeta WHERE orgid=? AND documentid=?"+filter, p.Context.OrgID, documentID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("Unable to execute select document page meta for org %s and document %s", p.Context.OrgID, documentID), err)
|
log.Error(fmt.Sprintf("Unable to execute select document page meta for org %s and document %s", p.Context.OrgID, documentID), err)
|
||||||
|
|
|
@ -168,6 +168,7 @@ CREATE TABLE IF NOT EXISTS `pagemeta` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`pageid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`pageid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`rawbody` LONGBLOB,
|
`rawbody` LONGBLOB,
|
||||||
`config` JSON,
|
`config` JSON,
|
||||||
|
@ -266,3 +267,16 @@ INSERT INTO `config` VALUES ('LICENSE','{\"token\": \"\",\"endpoint\": \"https:/
|
||||||
INSERT INTO `config` VALUES ('META','{\"database\": \"db_00000.sql\"}');
|
INSERT INTO `config` VALUES ('META','{\"database\": \"db_00000.sql\"}');
|
||||||
INSERT INTO `config` VALUES ('SECTION-GITHUB', '{\"clientID\": \"\", \"clientSecret\": \"\", \"authorizationCallbackURL\": \"https://localhost:5001/api/public/validate?section=github\"}');
|
INSERT INTO `config` VALUES ('SECTION-GITHUB', '{\"clientID\": \"\", \"clientSecret\": \"\", \"authorizationCallbackURL\": \"https://localhost:5001/api/public/validate?section=github\"}');
|
||||||
INSERT INTO `config` VALUES ('SECTION-TRELLO','{\"appKey\": \"\"}');
|
INSERT INTO `config` VALUES ('SECTION-TRELLO','{\"appKey\": \"\"}');
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `userconfig`;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `userconfig` (
|
||||||
|
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`key` CHAR(225) NOT NULL,
|
||||||
|
`config` JSON,
|
||||||
|
UNIQUE INDEX `idx_userconfig_orguserkey` (`orgid`, `userid`, `key` ASC) )
|
||||||
|
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||||
|
|
||||||
|
-- TODO insert userid into pagemeta table
|
||||||
|
-- ALTER TABLE `pagemeta` ADD `userid` CHAR(16) NOT NULL COLLATE utf8_bin AFTER `orgid`;
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render converts Gemini data into HTML suitable for browser rendering.
|
// Render converts Gemini data into HTML suitable for browser rendering.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
var items []geminiItem
|
var items []geminiItem
|
||||||
var payload = geminiRender{}
|
var payload = geminiRender{}
|
||||||
var c = geminiConfig{}
|
var c = geminiConfig{}
|
||||||
|
@ -64,7 +64,7 @@ func (*Provider) Render(config, data string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command handles authentication, workspace listing and items retrieval.
|
// Command handles authentication, workspace listing and items retrieval.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
method := query.Get("method")
|
method := query.Get("method")
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) (newData string) {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) (newData string) {
|
||||||
var c = geminiConfig{}
|
var c = geminiConfig{}
|
||||||
err := json.Unmarshal([]byte(config), &c)
|
err := json.Unmarshal([]byte(config), &c)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ package github
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -64,9 +65,22 @@ func authorizationCallbackURL() string {
|
||||||
// NOTE: URL value must have the path and query "/api/public/validate?section=github"
|
// NOTE: URL value must have the path and query "/api/public/validate?section=github"
|
||||||
return request.ConfigString(meta.ConfigHandle(), "authorizationCallbackURL")
|
return request.ConfigString(meta.ConfigHandle(), "authorizationCallbackURL")
|
||||||
}
|
}
|
||||||
|
func validateToken(ptoken string) error {
|
||||||
|
// Github authorization check
|
||||||
|
authClient := gogithub.NewClient((&gogithub.BasicAuthTransport{
|
||||||
|
Username: clientID(),
|
||||||
|
Password: clientSecret(),
|
||||||
|
}).Client())
|
||||||
|
_, _, err := authClient.Authorizations.Check(clientID(), ptoken)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func secretsJSON(token string) string {
|
||||||
|
return `{"token":"` + strings.TrimSpace(token) + `"}`
|
||||||
|
}
|
||||||
|
|
||||||
// Command to run the various functions required...
|
// Command to run the various functions required...
|
||||||
func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (p *Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
method := query.Get("method")
|
method := query.Get("method")
|
||||||
|
|
||||||
|
@ -99,6 +113,25 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the secret token in the database
|
||||||
|
ptoken := ctx.GetSecrets("token")
|
||||||
|
|
||||||
|
switch method {
|
||||||
|
|
||||||
|
case "saveSecret": // secret Token update code
|
||||||
|
|
||||||
|
// write the new one, direct from JS
|
||||||
|
if err = ctx.SaveSecrets(string(body)); err != nil {
|
||||||
|
log.Error("github settoken configuration", err)
|
||||||
|
provider.WriteError(w, "github", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
provider.WriteEmpty(w)
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the config from the client-side
|
||||||
config := githubConfig{}
|
config := githubConfig{}
|
||||||
err = json.Unmarshal(body, &config)
|
err = json.Unmarshal(body, &config)
|
||||||
|
|
||||||
|
@ -109,17 +142,29 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Clean()
|
config.Clean()
|
||||||
|
// always use DB version of the token
|
||||||
if len(config.Token) == 0 {
|
config.Token = ptoken
|
||||||
msg := "Missing token"
|
|
||||||
log.ErrorString("github: " + msg)
|
|
||||||
provider.WriteMessage(w, "gitub", msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
client := p.githubClient(config)
|
client := p.githubClient(config)
|
||||||
|
|
||||||
switch method {
|
switch method { // the main data handling switch
|
||||||
|
|
||||||
|
case "checkAuth":
|
||||||
|
|
||||||
|
if len(ptoken) == 0 {
|
||||||
|
err = errors.New("empty github token")
|
||||||
|
} else {
|
||||||
|
err = validateToken(ptoken)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// token now invalid, so wipe it
|
||||||
|
ctx.SaveSecrets("") // ignore error, already in an error state
|
||||||
|
log.Error("github check token validation", err)
|
||||||
|
provider.WriteError(w, "github", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
provider.WriteEmpty(w)
|
||||||
|
return
|
||||||
|
|
||||||
case tagCommitsData:
|
case tagCommitsData:
|
||||||
|
|
||||||
|
@ -208,7 +253,7 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteError(w, "github", err)
|
provider.WriteError(w, "github", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for kr, vr := range repos {
|
for _, vr := range repos {
|
||||||
private := ""
|
private := ""
|
||||||
if *vr.Private {
|
if *vr.Private {
|
||||||
private = " (private)"
|
private = " (private)"
|
||||||
|
@ -216,7 +261,7 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
render = append(render,
|
render = append(render,
|
||||||
githubRepo{
|
githubRepo{
|
||||||
Name: config.Owner + "/" + *vr.Name + private,
|
Name: config.Owner + "/" + *vr.Name + private,
|
||||||
ID: fmt.Sprintf("%s:%s:%d", config.Owner, *vr.Name, kr),
|
ID: fmt.Sprintf("%s:%s", config.Owner, *vr.Name),
|
||||||
Owner: config.Owner,
|
Owner: config.Owner,
|
||||||
Repo: *vr.Name,
|
Repo: *vr.Name,
|
||||||
Private: *vr.Private,
|
Private: *vr.Private,
|
||||||
|
@ -229,6 +274,7 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteJSON(w, render)
|
provider.WriteJSON(w, render)
|
||||||
|
|
||||||
case "branches":
|
case "branches":
|
||||||
|
|
||||||
if config.Owner == "" || config.Repo == "" {
|
if config.Owner == "" || config.Repo == "" {
|
||||||
provider.WriteJSON(w, []githubBranch{}) // we have nothing to return
|
provider.WriteJSON(w, []githubBranch{}) // we have nothing to return
|
||||||
return
|
return
|
||||||
|
@ -244,7 +290,7 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
for kc, vb := range branches {
|
for kc, vb := range branches {
|
||||||
render[kc] = githubBranch{
|
render[kc] = githubBranch{
|
||||||
Name: *vb.Name,
|
Name: *vb.Name,
|
||||||
ID: fmt.Sprintf("%s:%s:%s:%d", config.Owner, config.Repo, *vb.Name, kc),
|
ID: fmt.Sprintf("%s:%s:%s", config.Owner, config.Repo, *vb.Name),
|
||||||
Included: false,
|
Included: false,
|
||||||
URL: "https://github.com/" + config.Owner + "/" + config.Repo + "/tree/" + *vb.Name,
|
URL: "https://github.com/" + config.Owner + "/" + config.Repo + "/tree/" + *vb.Name,
|
||||||
}
|
}
|
||||||
|
@ -253,6 +299,7 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteJSON(w, render)
|
provider.WriteJSON(w, render)
|
||||||
|
|
||||||
case "labels":
|
case "labels":
|
||||||
|
|
||||||
if config.Owner == "" || config.Repo == "" {
|
if config.Owner == "" || config.Repo == "" {
|
||||||
provider.WriteJSON(w, []githubBranch{}) // we have nothing to return
|
provider.WriteJSON(w, []githubBranch{}) // we have nothing to return
|
||||||
return
|
return
|
||||||
|
@ -277,6 +324,7 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteJSON(w, render)
|
provider.WriteJSON(w, render)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
log.ErrorString("Github connector unknown method: " + method)
|
log.ErrorString("Github connector unknown method: " + method)
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
@ -573,7 +621,7 @@ func (*Provider) getCommits(client *gogithub.Client, config githubConfig) ([]git
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh ... gets the latest version
|
// Refresh ... gets the latest version
|
||||||
func (p *Provider) Refresh(configJSON, data string) string {
|
func (p *Provider) Refresh(ctx *provider.Context, configJSON, data string) string {
|
||||||
var c = githubConfig{}
|
var c = githubConfig{}
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(configJSON), &c)
|
err := json.Unmarshal([]byte(configJSON), &c)
|
||||||
|
@ -584,6 +632,7 @@ func (p *Provider) Refresh(configJSON, data string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Clean()
|
c.Clean()
|
||||||
|
c.Token = ctx.GetSecrets("token")
|
||||||
|
|
||||||
switch c.ReportInfo.ID {
|
switch c.ReportInfo.ID {
|
||||||
/*case "issuenum_data":
|
/*case "issuenum_data":
|
||||||
|
@ -634,7 +683,7 @@ func (p *Provider) Refresh(configJSON, data string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render ... just returns the data given, suitably formatted
|
// Render ... just returns the data given, suitably formatted
|
||||||
func (p *Provider) Render(config, data string) string {
|
func (p *Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
payload := githubRender{}
|
payload := githubRender{}
|
||||||
|
@ -648,6 +697,8 @@ func (p *Provider) Render(config, data string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Clean()
|
c.Clean()
|
||||||
|
c.Token = ctx.GetSecrets("token")
|
||||||
|
|
||||||
payload.Config = c
|
payload.Config = c
|
||||||
payload.Repo = c.RepoInfo
|
payload.Repo = c.RepoInfo
|
||||||
payload.Limit = c.BranchLines
|
payload.Limit = c.BranchLines
|
||||||
|
|
|
@ -13,14 +13,13 @@ package github
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/documize/community/wordsmith/log"
|
"github.com/documize/community/wordsmith/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tagIssuesData = "issues_data"
|
const tagIssuesData = "issuesData"
|
||||||
const tagCommitsData = "commits_data"
|
const tagCommitsData = "commitsData"
|
||||||
|
|
||||||
type githubRender struct {
|
type githubRender struct {
|
||||||
Config githubConfig
|
Config githubConfig
|
||||||
|
@ -218,8 +217,9 @@ type githubIssueActivity struct {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type githubConfig struct {
|
type githubConfig struct {
|
||||||
AppKey string `json:"appKey"` // TODO keep?
|
Token string `json:"-"` // NOTE very important that the secret Token is not leaked to the client side, so "-"
|
||||||
Token string `json:"token"`
|
UserID string `json:"userId"`
|
||||||
|
PageID string `json:"pageId"`
|
||||||
Owner string `json:"owner_name"`
|
Owner string `json:"owner_name"`
|
||||||
Repo string `json:"repo_name"`
|
Repo string `json:"repo_name"`
|
||||||
Branch string `json:"branch"`
|
Branch string `json:"branch"`
|
||||||
|
@ -239,8 +239,6 @@ type githubConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *githubConfig) Clean() {
|
func (c *githubConfig) Clean() {
|
||||||
c.AppKey = strings.TrimSpace(c.AppKey) // TODO keep?
|
|
||||||
c.Token = strings.TrimSpace(c.Token)
|
|
||||||
c.Owner = c.OwnerInfo.Name
|
c.Owner = c.OwnerInfo.Name
|
||||||
c.Repo = c.RepoInfo.Repo
|
c.Repo = c.RepoInfo.Repo
|
||||||
for _, l := range c.Lists {
|
for _, l := range c.Lists {
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,18 +36,18 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render converts markdown data into HTML suitable for browser rendering.
|
// Render converts markdown data into HTML suitable for browser rendering.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
result := blackfriday.MarkdownCommon([]byte(data))
|
result := blackfriday.MarkdownCommon([]byte(data))
|
||||||
|
|
||||||
return string(result)
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ type papertrailEvent struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type papertrailConfig struct {
|
type papertrailConfig struct {
|
||||||
APIToken string `json:"APIToken"`
|
APIToken string `json:"APIToken"` // only contains the correct token just after it is typed in
|
||||||
Query string `json:"query"`
|
Query string `json:"query"`
|
||||||
Max int `json:"max"`
|
Max int `json:"max"`
|
||||||
Group papertrailOption `json:"group"`
|
Group papertrailOption `json:"group"`
|
||||||
|
|
|
@ -42,7 +42,7 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render converts Papertrail data into HTML suitable for browser rendering.
|
// Render converts Papertrail data into HTML suitable for browser rendering.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
var search papertrailSearch
|
var search papertrailSearch
|
||||||
var events []papertrailEvent
|
var events []papertrailEvent
|
||||||
var payload = papertrailRender{}
|
var payload = papertrailRender{}
|
||||||
|
@ -51,6 +51,8 @@ func (*Provider) Render(config, data string) string {
|
||||||
json.Unmarshal([]byte(data), &search)
|
json.Unmarshal([]byte(data), &search)
|
||||||
json.Unmarshal([]byte(config), &c)
|
json.Unmarshal([]byte(config), &c)
|
||||||
|
|
||||||
|
c.APIToken = ctx.GetSecrets("APIToken")
|
||||||
|
|
||||||
max := len(search.Events)
|
max := len(search.Events)
|
||||||
if c.Max < max {
|
if c.Max < max {
|
||||||
max = c.Max
|
max = c.Max
|
||||||
|
@ -74,7 +76,7 @@ func (*Provider) Render(config, data string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command handles authentication, workspace listing and items retrieval.
|
// Command handles authentication, workspace listing and items retrieval.
|
||||||
func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (p *Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
method := query.Get("method")
|
method := query.Get("method")
|
||||||
|
|
||||||
|
@ -101,6 +103,10 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
config.Clean()
|
config.Clean()
|
||||||
|
|
||||||
|
if config.APIToken == provider.SecretReplacement {
|
||||||
|
config.APIToken = ctx.GetSecrets("APIToken")
|
||||||
|
}
|
||||||
|
|
||||||
if len(config.APIToken) == 0 {
|
if len(config.APIToken) == 0 {
|
||||||
provider.WriteMessage(w, me, "Missing API token")
|
provider.WriteMessage(w, me, "Missing API token")
|
||||||
return
|
return
|
||||||
|
@ -108,14 +114,14 @@ func (p *Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
switch method {
|
switch method {
|
||||||
case "auth":
|
case "auth":
|
||||||
auth(config, w, r)
|
auth(ctx, config, w, r)
|
||||||
case "options":
|
case "options":
|
||||||
options(config, w, r)
|
options(config, w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) (newData string) {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) (newData string) {
|
||||||
var c = papertrailConfig{}
|
var c = papertrailConfig{}
|
||||||
err := json.Unmarshal([]byte(config), &c)
|
err := json.Unmarshal([]byte(config), &c)
|
||||||
|
|
||||||
|
@ -126,6 +132,8 @@ func (*Provider) Refresh(config, data string) (newData string) {
|
||||||
|
|
||||||
c.Clean()
|
c.Clean()
|
||||||
|
|
||||||
|
c.APIToken = ctx.GetSecrets("APIToken")
|
||||||
|
|
||||||
if len(c.APIToken) == 0 {
|
if len(c.APIToken) == 0 {
|
||||||
log.Error("missing API token", err)
|
log.Error("missing API token", err)
|
||||||
return
|
return
|
||||||
|
@ -149,7 +157,7 @@ func (*Provider) Refresh(config, data string) (newData string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func auth(config papertrailConfig, w http.ResponseWriter, r *http.Request) {
|
func auth(ctx *provider.Context, config papertrailConfig, w http.ResponseWriter, r *http.Request) {
|
||||||
result, err := fetchEvents(config)
|
result, err := fetchEvents(config)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -162,6 +170,8 @@ func auth(config papertrailConfig, w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.IfErr(ctx.SaveSecrets(`{"APIToken":"` + config.APIToken + `"}`))
|
||||||
|
|
||||||
provider.WriteJSON(w, result)
|
provider.WriteJSON(w, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,14 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/documize/community/documize/api/request"
|
||||||
"github.com/documize/community/wordsmith/log"
|
"github.com/documize/community/wordsmith/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SecretReplacement is a constant used to replace secrets in data-structures when required.
|
||||||
|
// 8 stars.
|
||||||
|
const SecretReplacement = "********"
|
||||||
|
|
||||||
// sectionsMap is where individual sections register themselves.
|
// sectionsMap is where individual sections register themselves.
|
||||||
var sectionsMap = make(map[string]Provider)
|
var sectionsMap = make(map[string]Provider)
|
||||||
|
|
||||||
|
@ -43,10 +48,26 @@ func (t *TypeMeta) ConfigHandle() string {
|
||||||
|
|
||||||
// Provider represents a 'page' in a document.
|
// Provider represents a 'page' in a document.
|
||||||
type Provider interface {
|
type Provider interface {
|
||||||
Meta() TypeMeta // Meta returns section details
|
Meta() TypeMeta // Meta returns section details
|
||||||
Command(w http.ResponseWriter, r *http.Request) // Command is general-purpose method that can return data to UI
|
Command(ctx *Context, w http.ResponseWriter, r *http.Request) // Command is general-purpose method that can return data to UI
|
||||||
Render(config, data string) string // Render converts section data into presentable HTML
|
Render(ctx *Context, config, data string) string // Render converts section data into presentable HTML
|
||||||
Refresh(config, data string) string // Refresh returns latest data
|
Refresh(ctx *Context, config, data string) string // Refresh returns latest data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context describes the environment the section code runs in
|
||||||
|
type Context struct {
|
||||||
|
OrgID string
|
||||||
|
UserID string
|
||||||
|
prov Provider
|
||||||
|
inCommand bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContext is a convenience function.
|
||||||
|
func NewContext(orgid, userid string) *Context {
|
||||||
|
if orgid == "" || userid == "" {
|
||||||
|
log.Error("NewContext incorrect orgid:"+orgid+" userid:"+userid, errors.New("bad section context"))
|
||||||
|
}
|
||||||
|
return &Context{OrgID: orgid, UserID: userid}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register makes document section type available
|
// Register makes document section type available
|
||||||
|
@ -71,10 +92,12 @@ func GetSectionMeta() []TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command passes parameters to the given section id, the returned bool indicates success.
|
// Command passes parameters to the given section id, the returned bool indicates success.
|
||||||
func Command(section string, w http.ResponseWriter, r *http.Request) bool {
|
func Command(section string, ctx *Context, w http.ResponseWriter, r *http.Request) bool {
|
||||||
s, ok := sectionsMap[section]
|
s, ok := sectionsMap[section]
|
||||||
if ok {
|
if ok {
|
||||||
s.Command(w, r)
|
ctx.prov = s
|
||||||
|
ctx.inCommand = true
|
||||||
|
s.Command(ctx, w, r)
|
||||||
}
|
}
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
@ -91,19 +114,21 @@ func Callback(section string, w http.ResponseWriter, r *http.Request) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render runs that operation for the given section id, the returned bool indicates success.
|
// Render runs that operation for the given section id, the returned bool indicates success.
|
||||||
func Render(section, config, data string) (string, bool) {
|
func Render(section string, ctx *Context, config, data string) (string, bool) {
|
||||||
s, ok := sectionsMap[section]
|
s, ok := sectionsMap[section]
|
||||||
if ok {
|
if ok {
|
||||||
return s.Render(config, data), true
|
ctx.prov = s
|
||||||
|
return s.Render(ctx, config, data), true
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh returns the latest data for a section.
|
// Refresh returns the latest data for a section.
|
||||||
func Refresh(section, config, data string) (string, bool) {
|
func Refresh(section string, ctx *Context, config, data string) (string, bool) {
|
||||||
s, ok := sectionsMap[section]
|
s, ok := sectionsMap[section]
|
||||||
if ok {
|
if ok {
|
||||||
return s.Refresh(config, data), true
|
ctx.prov = s
|
||||||
|
return s.Refresh(ctx, config, data), true
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
@ -174,6 +199,28 @@ func WriteForbidden(w http.ResponseWriter) {
|
||||||
log.IfErr(err)
|
log.IfErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Secrets handling
|
||||||
|
|
||||||
|
// SaveSecrets for the current user/org combination.
|
||||||
|
// The secrets must be in the form of a JSON format string, for example `{"mysecret":"lover"}`.
|
||||||
|
// An empty string signifies no valid secrets for this user/org combination.
|
||||||
|
// Note that this function can only be called within the Command method of a section.
|
||||||
|
func (c *Context) SaveSecrets(JSONobj string) error {
|
||||||
|
if !c.inCommand {
|
||||||
|
return errors.New("SaveSecrets() may only be called from within Command()")
|
||||||
|
}
|
||||||
|
return request.UserConfigSetJSON(c.OrgID, c.UserID, c.prov.Meta().ContentType, JSONobj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecrets for the current context user/org.
|
||||||
|
// For example (see SaveSecrets example): thisContext.GetSecrets("mysecret")
|
||||||
|
// JSONpath format is defined at https://dev.mysql.com/doc/refman/5.7/en/json-path-syntax.html .
|
||||||
|
// An empty JSONpath returns the whole JSON object, as JSON.
|
||||||
|
// Errors return the empty string.
|
||||||
|
func (c *Context) GetSecrets(JSONpath string) string {
|
||||||
|
return request.UserConfigGetJSON(c.OrgID, c.UserID, c.prov.Meta().ContentType, JSONpath)
|
||||||
|
}
|
||||||
|
|
||||||
// sort sections in order that that should be presented.
|
// sort sections in order that that should be presented.
|
||||||
type sectionsToSort []TypeMeta
|
type sectionsToSort []TypeMeta
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ func Register() {
|
||||||
provider.Register("trello", &trello.Provider{})
|
provider.Register("trello", &trello.Provider{})
|
||||||
provider.Register("wysiwyg", &wysiwyg.Provider{})
|
provider.Register("wysiwyg", &wysiwyg.Provider{})
|
||||||
provider.Register("zendesk", &zendesk.Provider{})
|
provider.Register("zendesk", &zendesk.Provider{})
|
||||||
|
|
||||||
p := provider.List()
|
p := provider.List()
|
||||||
log.Info(fmt.Sprintf("Documize registered %d smart sections", len(p)))
|
log.Info(fmt.Sprintf("Documize registered %d smart sections", len(p)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render sends back data as-is (HTML).
|
// Render sends back data as-is (HTML).
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
method := query.Get("method")
|
method := query.Get("method")
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
raw := []trelloListCards{}
|
raw := []trelloListCards{}
|
||||||
payload := trelloRender{}
|
payload := trelloRender{}
|
||||||
var c = trelloConfig{}
|
var c = trelloConfig{}
|
||||||
|
@ -163,7 +163,7 @@ func (*Provider) Render(config, data string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
var c = trelloConfig{}
|
var c = trelloConfig{}
|
||||||
json.Unmarshal([]byte(config), &c)
|
json.Unmarshal([]byte(config), &c)
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render returns data as-is (HTML).
|
// Render returns data as-is (HTML).
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@ func (*Provider) Meta() provider.TypeMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command stub.
|
// Command stub.
|
||||||
func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
|
func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
provider.WriteEmpty(w)
|
provider.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render just sends back HMTL as-is.
|
// Render just sends back HMTL as-is.
|
||||||
func (*Provider) Render(config, data string) string {
|
func (*Provider) Render(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh just sends back data as-is.
|
// Refresh just sends back data as-is.
|
||||||
func (*Provider) Refresh(config, data string) string {
|
func (*Provider) Refresh(ctx *provider.Context, config, data string) string {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue