Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GSoC19] Rc articles frontend #6

Open
wants to merge 33 commits into
base: rc_articles
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
cc47740
add option to add user from RC_API
shubhsherl May 25, 2019
5551d55
add login with access_token and user_id
shubhsherl May 27, 2019
6b8bf8b
add channel validation
shubhsherl May 30, 2019
9369009
add redirect from rc
shubhsherl Jun 1, 2019
ff33170
add rcapi and improve code
shubhsherl Jun 4, 2019
f436db5
fix minor bug
shubhsherl Jun 6, 2019
6684ab0
change auth method
shubhsherl Jun 14, 2019
0e90a98
add login with access_token and user_id
shubhsherl May 27, 2019
028c5d5
add redirect from rc
shubhsherl Jun 1, 2019
bbf96c7
add rcapi and improve code
shubhsherl Jun 4, 2019
a263c2e
add channel validation
shubhsherl Jun 6, 2019
0addd39
improve rc-utils structure and add sample message for announcement
shubhsherl Jun 7, 2019
b99bf7f
improve rc-utils structure
shubhsherl Jun 8, 2019
d8c17de
fix message icon
shubhsherl Jun 8, 2019
005dce5
add webhook for announcing post, remove postMessage
shubhsherl Jun 10, 2019
3a826b5
change avatar
shubhsherl Jun 11, 2019
748e840
add missing import and fix url
shubhsherl Jun 14, 2019
0509a44
add login with access_token and user_id
shubhsherl May 27, 2019
3f3a63b
add redirect from rc
shubhsherl Jun 1, 2019
c6e47d4
add rcapi and improve code
shubhsherl Jun 4, 2019
404f55b
add channel validation
shubhsherl Jun 6, 2019
b7a2445
improve rc-utils structure and add sample message for announcement
shubhsherl Jun 7, 2019
f374e5e
improve rc-utils structure
shubhsherl Jun 8, 2019
ceba1f5
add webhook for announcing post, remove postMessage
shubhsherl Jun 10, 2019
6af7be9
add collaboration def setting and validator
shubhsherl Jun 10, 2019
95386c2
add collaborate schema
shubhsherl Jun 13, 2019
a711943
add api to check if user can collaborate
shubhsherl Jun 15, 2019
b1ce429
remove unnecessary file and collaborate user after check
shubhsherl Jun 17, 2019
58699f5
check setting while collaborating
shubhsherl Jun 17, 2019
b1c8634
check setting while collaborating
shubhsherl Jun 17, 2019
5a6cdb8
fix an issue in client
shubhsherl Jun 20, 2019
84a6942
bump to new commit client
shubhsherl Jun 21, 2019
69efabb
remove invite model
shubhsherl Jun 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/client
14 changes: 13 additions & 1 deletion core/server/api/shared/http.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const debug = require('ghost-ignition').debug('api:shared:http');
const shared = require('../shared');
const models = require('../../models');
const _ = require('lodash');

/**
* @description HTTP wrapper.
Expand All @@ -18,6 +19,16 @@ const http = (apiImpl) => {
let apiKey = null;
let integration = null;
let user = null;
let rc_uid = null;
let rc_token = null;

if(req.headers && req.headers.cookie)
_.forEach(req.headers.cookie.split(';'), (v)=>{
if(v.includes('rc_uid'))
rc_uid = v.split('=')[1];
if(v.includes('rc_token'))
rc_token = v.split('=')[1];
});

if (req.api_key) {
apiKey = {
Expand All @@ -39,6 +50,8 @@ const http = (apiImpl) => {
file: req.file,
files: req.files,
query: req.query,
rc_uid: rc_uid,
rc_token: rc_token,
params: req.params,
user: req.user,
context: {
Expand Down Expand Up @@ -93,7 +106,6 @@ const http = (apiImpl) => {
docName: frame.docName,
method: frame.method
};

next(err);
});
};
Expand Down
121 changes: 113 additions & 8 deletions core/server/api/v0.1/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const Promise = require('bluebird'),
mail = require('../../services/mail'),
urlService = require('../../services/url'),
localUtils = require('./utils'),
rcUtils = require('../v2/utils/rc-utils'),
models = require('../../models'),
web = require('../../web'),
mailAPI = require('./mail'),
Expand Down Expand Up @@ -61,14 +62,25 @@ function setupTasks(setupData) {
let tasks;

function validateData(setupData) {
return localUtils.checkObject(setupData, 'setup').then((checked) => {
const data = checked.setup[0];

const id = setupData['setup'][0].rc_id;
const token = setupData['setup'][0].rc_token;
const blogTitle = setupData['setup'][0].blogTitle;
const rcUrl = setupData['setup'][0].rc_url;
const announceToken = setupData['setup'][0].announce_token;
const collabToken = setupData['setup'][0].collaboration_token;
return rcUtils.checkAdmin(rcUrl, id, token).then((data) => {
const email = data.emails[0].address;
return {
name: data.name,
email: data.email,
password: data.password,
blogTitle: data.blogTitle,
rc_id: id,
rc_username: data.username,
profile_image: data.avatarUrl,
email: email,
password: "qwe123qwe123",//TODO set random password
blogTitle: blogTitle,
announce_token: announceToken,
collaboration_token: collabToken,
serverUrl: rcUrl,
status: 'active'
};
});
Expand Down Expand Up @@ -97,6 +109,9 @@ function setupTasks(setupData) {
function doSettings(data) {
const user = data.user,
blogTitle = data.userData.blogTitle,
serverUrl = data.userData.serverUrl,
announceToken = data.userData.announce_token,
collabToken = data.userData.collaboration_token,
context = {context: {user: data.user.id}};

let userSettings;
Expand All @@ -106,7 +121,10 @@ function setupTasks(setupData) {
}

userSettings = [
{key: 'server_url', value: serverUrl},
{key: 'title', value: blogTitle.trim()},
{key: 'announce_token', value: announceToken},
{key: 'collaboration_token', value: collabToken},
{key: 'description', value: common.i18n.t('common.api.authentication.sampleBlogDescription')}
];

Expand Down Expand Up @@ -437,6 +455,92 @@ authentication = {
return pipeline(tasks, invitation);
},

/**
* ### Add Users
* @param {Object} invitation an invitation object
* @returns {Promise<Object>}
*/
addUser(invitation, option) {
let tasks,
invite;
const options = {context: {internal: true}, withRelated: ['roles']};
const localOptions = {context: {internal: true}};
// 1. if admin adds user, option.
// 2. if user creating account, invitation.
const rc_uid = option.rc_uid || invitation.user[0].rc_uid;
const rc_token = option.rc_token || invitation.user[0].rc_token;

function validateInvitation(invitation) {
return models.Settings.findOne({ key: 'invite_only' }, localOptions)
.then((setting) => {
const inviteOnly = setting.attributes.value;
return rcUtils.getMe(rc_uid, rc_token)
.then((invitedBy) => {
if (!invitedBy.success) {
throw new common.errors.NotFoundError({ message: "User not found. Make Sure you are logged in on RC." });
}
if (inviteOnly) { //Check that rc_uid is of Owner/Admin
return models.User.findOne({ rc_id: rc_uid, role: 'Owner'||'Administrator', status: 'all'}, options)
.then((user) => {
if (user) {
return invitation;
} else {
throw new common.errors.NotFoundError({ message: "You are not authorized to add new authors" });
}
});
} else {// Self Invitation
return invitation;
}
});
});
}

function processInvitation(invitation) {
const data = invitation.user[0];
return rcUtils.getUser(rc_uid, rc_token, data.rc_username)
.then((user) => {
if (user.success && user.user) {
const u = user.user;
if(!u.emails){
throw new common.errors.NotFoundError({ message: "Cannot create account without email." });
}
const email = u.emails[0].address;
const role = data.role.name||'Author';
return models.Role.findOne({name: role})
.then((r) => {
return models.User.add({
rc_id: u._id,
rc_username: u.username,
email: email,
name: u.name,
password: "qwe123qwe123",//TODO Random password
roles: [r]
}, localOptions);
});
} else {
throw new common.errors.NotFoundError({message: "User not found. Make Sure you are logged in on RC."});
}
});
}

function formatResponse() {
return {
invitation: [
{message: 'User Added'}
]
};
}

tasks = [
assertSetupCompleted(true),
validateInvitation,
processInvitation,
formatResponse
];

return pipeline(tasks, invitation);
},

/**
* ### Check for invitation
* @param {Object} options
Expand Down Expand Up @@ -513,7 +617,7 @@ authentication = {
},

/**
* Executes the setup tasks and sends an email to the owner
* Executes the setup tasks and get access_token and user_id and verify with rc-utils
* @param {Object} setupDetails
* @return {Promise<Object>} a user api payload
*/
Expand Down Expand Up @@ -566,7 +670,8 @@ authentication = {
tasks = [
assertSetupCompleted(false),
doSetup,
sendNotification,
// TODO: add mail service from RC.
// sendNotification,
formatResponse
];

Expand Down
10 changes: 9 additions & 1 deletion core/server/api/v0.1/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// Ghost's JSON API is integral to the workings of Ghost, regardless of whether you want to access data internally,
// from a theme, an app, or from an external app, you'll use the Ghost JSON API to do so.

const {isEmpty} = require('lodash');
const {isEmpty, forEach} = require('lodash');
const Promise = require('bluebird');
const models = require('../../models');
const urlService = require('../../services/url');
Expand Down Expand Up @@ -272,6 +272,14 @@ const http = (apiMethod) => {
}
});

if(req.headers && req.headers.cookie)
forEach(req.headers.cookie.split(';'), (v)=>{
if(v.includes('rc_uid'))
options.rc_uid = v.split('=')[1];
if(v.includes('rc_token'))
options.rc_token = v.split('=')[1];
});

if (req.files) {
options.files = req.files;
}
Expand Down
4 changes: 2 additions & 2 deletions core/server/api/v2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ module.exports = {
return shared.pipeline(require('./posts'), localUtils);
},

get invites() {
return shared.pipeline(require('./invites'), localUtils);
get rcapi() {
return shared.pipeline(require('./rcapi'), localUtils);
},

get mail() {
Expand Down
Loading