Prevent unauthorized CMS access (#323) and enable use of GitHub Enterprise (#491)

* Prevent unauthorized CMS access and enable use of GitHub Enterprise
This commit is contained in:
tortilaman 2017-08-01 20:28:03 -07:00 committed by Benaiah Mischenko
parent b294110db7
commit 6805a6936d
6 changed files with 39 additions and 7 deletions

2
.gitignore vendored
View File

@ -6,3 +6,5 @@ npm-debug.log
.tern-project
yarn-error.log
.vscode/
manifest.yml
.imdone/

View File

@ -1,4 +1,7 @@
import { currentBackend } from '../backends/backend';
import { actions as notifActions } from 'redux-notifications';
const { notifSend } = notifActions;
export const AUTH_REQUEST = 'AUTH_REQUEST';
export const AUTH_SUCCESS = 'AUTH_SUCCESS';
@ -60,6 +63,11 @@ export function loginUser(credentials) {
dispatch(authenticate(user));
})
.catch((error) => {
dispatch(notifSend({
message: `${ error.message }`,
kind: 'warning',
dismissAfter: 8000,
}));
dispatch(authError(error));
});
};

View File

@ -19,6 +19,19 @@ export default class API {
return this.request("/user");
}
isCollaborator(user) {
return this.request('/user/repos').then((repos) => {
let contributor = false
for (const repo of repos) {
if (repo.full_name === this.repo && repo.permissions.push) contributor = true;
}
return contributor;
}).catch((error) => {
console.error("Problem with response of /user/repos from GitHub");
throw error;
})
}
requestHeaders(headers = {}) {
const baseHeader = {
"Content-Type": "application/json",
@ -241,7 +254,6 @@ export default class API {
persistFiles(entry, mediaFiles, options) {
const uploadPromises = [];
const files = mediaFiles.concat(entry);
files.forEach((file) => {
if (file.uploaded) { return; }

View File

@ -1,5 +1,6 @@
.root {
display: flex;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
height: 100vh;

View File

@ -2,6 +2,8 @@ import React from 'react';
import Button from 'react-toolbox/lib/button';
import Authenticator from '../../lib/netlify-auth';
import { Icon } from '../../components/UI';
import { Notifs } from 'redux-notifications';
import { Toast } from '../../components/UI/index';
import styles from './AuthenticationPage.css';
export default class AuthenticationPage extends React.Component {
@ -16,7 +18,7 @@ export default class AuthenticationPage extends React.Component {
const cfg = {
base_url: this.props.base_url,
site_id: (document.location.host.split(':')[0] === 'localhost') ? 'cms.netlify.com' : this.props.siteId
}
};
const auth = new Authenticator(cfg);
auth.authenticate({ provider: 'github', scope: 'repo' }, (err, data) => {
@ -33,6 +35,7 @@ export default class AuthenticationPage extends React.Component {
return (
<section className={styles.root}>
<Notifs CustomComponent={Toast} />
{loginError && <p>{loginError}</p>}
<Button
className={styles.button}

View File

@ -15,6 +15,7 @@ export default class GitHub {
this.repo = config.getIn(["backend", "repo"], "");
this.branch = config.getIn(["backend", "branch"], "master");
this.api_root = config.getIn(["backend", "api_root"], "https://api.github.com");
this.token = '';
}
@ -29,11 +30,16 @@ export default class GitHub {
authenticate(state) {
this.token = state.token;
this.api = new API({ token: this.token, branch: this.branch, repo: this.repo });
return this.api.user().then((user) => {
user.token = state.token;
return user;
});
this.api = new API({ token: this.token, branch: this.branch, repo: this.repo, api_root: this.api_root });
return this.api.user().then(user =>
this.api.isCollaborator(user.login).then((isCollab) => {
// Unauthorized user
if (!isCollab) throw new Error("Your GitHub user account does not have access to this repo.");
// Authorized user
user.token = state.token;
return user;
})
);
}
getToken() {