Commit 238055ea authored by Andreas Åkre Solberg's avatar Andreas Åkre Solberg

New iteration. Added serverconfig and API async and more.

parent 285f7b07
import { createAction, createActions, handleActions, combineActions } from 'redux-actions'
import promiseMiddleware from 'redux-promise';
import { createActions} from 'redux-actions'
export const discoveryStart = createAction('discoveryStart')
const actionCreators = createActions({
discovery: {
start: hostname => (hostname),
completed: payload => (payload)
},
serverConfig: {
save: config => (config)
}
});
export default actionCreators
import React, { PureComponent } from 'react'
import {Navbar, Nav, NavItem, NavDropdown, MenuItem, Glyphicon, Jumbotron, Button} from 'react-bootstrap'
import {Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock} from 'react-bootstrap'
import {Alert, Navbar, Nav, NavItem, NavDropdown, MenuItem, Glyphicon, Jumbotron, Button} from 'react-bootstrap'
import {Panel, Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock} from 'react-bootstrap'
import FontAwesome from 'react-fontawesome'
const foo = () => {
console.log("AYA")
}
const defaultHost = "https://auth.dataporten.no/"
const defaultHost = "https://auth.dataporten.no"
class Component extends PureComponent {
......@@ -21,7 +16,8 @@ class Component extends PureComponent {
}
discoveryStart(e) {
console.log("Setting hostname")
console.log("Setting hostname", this.state.hostname)
console.log(this.props)
this.props.discoveryStart(this.state.hostname)
}
......@@ -30,9 +26,43 @@ class Component extends PureComponent {
this.setState({hostname: e.target.value})
}
handleAlertDismiss() {
console.error("TODO: Dismiss alert.")
// this.setState({hostname: e.target.value})
}
getErrorMessage() {
if (this.props.serverError) {
console.log(typeof this.props.serverError)
console.error(this.props.serverError)
return (
<Alert bsStyle="danger" onDismiss={this.handleAlertDismiss}>
<h4>Error performing OAuth Discovery</h4>
<p>{this.props.serverError.toString()}</p>
<p>
<span> or </span>
<Button onClick={this.handleAlertDismiss}>Hide error</Button>
</p>
</Alert>
)
}
return null
}
render() {
console.log("This state", this.props)
let errorMessage = null
if (this.props.serverError) {
errorMessage = (
<div>
<h2>Error performing OAuth Discovery</h2>
<p>{this.props.serverError}</p>
</div>
)
}
return (
<div>
<Panel header="OAuth Service Discovery" eventKey="1" collapsible={true} expanded={true}>
<FormGroup
className="gutter"
controlId="formBasicText"
......@@ -41,15 +71,19 @@ class Component extends PureComponent {
<FormControl
type="text"
bsSize="large"
defaultValue={defaultHost}
defaultValue={this.state.hostname}
placeholder="https://auth.yourplatform.org/"
onChange={this.updateHostfield.bind(this)}
/>
<HelpBlock>Fill out the hostname of your OAuth server. Will only work if your OAuth server support OAuth Discovery. If not, please enter configuration manually.</HelpBlock>
<HelpBlock>Fill out the hostname of your OAuth server. Will only work if your OAuth server support OpenID Connect Discovery. If not, please enter configuration manually.</HelpBlock>
</FormGroup>
<div><Button onClick={this.discoveryStart.bind(this)} bsStyle="primary"><Glyphicon glyph="book" /> Discovery OAuth Provider</Button></div>
</div>
{this.getErrorMessage()}
<div>
<Button onClick={this.discoveryStart.bind(this)} bsStyle="primary">
<FontAwesome name='magic' /> Discovery OAuth Provider
</Button>
</div>
</Panel>
)
}
......
import React from 'react'
import {Navbar, Nav, NavItem, NavDropdown, MenuItem, Glyphicon, Jumbotron, Button} from 'react-bootstrap'
import {Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock} from 'react-bootstrap'
import {Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock, PanelGroup, Panel} from 'react-bootstrap'
import HostnameController from '../containers/HostnameController'
import ServerConfigController from '../containers/ServerConfigController'
import WhiteBox from './WhiteBox'
const MainContent = () => (
<div>
<div className="container">
<Jumbotron className="uninett-color-lightBlue">
<h1>Play with OAuth 2.0</h1>
<h1>Play with OAuth 2.0</h1>
<p>Learn more about how OAuth 2.0 works, and explore OAuth protected APIs without entering any code.</p>
<HostnameController />
<p>Navigate the library of prepared applications, deploy and start using it within few minutes. This application platform is fully automated.</p>
<p>
<Button bsStyle="primary"><Glyphicon glyph="book" /> Library</Button>
<Button bsStyle="success"><Glyphicon glyph="modal-window" /> My installed applications</Button>
</p>
</Jumbotron>
<WhiteBox>
<HostnameController />
<ServerConfigController />
</WhiteBox>
</div>
</div>
......
import React, { PureComponent } from 'react'
import {Alert, InputGroup, Navbar, Nav, NavItem, NavDropdown, MenuItem, Glyphicon, Jumbotron, Button} from 'react-bootstrap'
import {Panel, Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock} from 'react-bootstrap'
import FontAwesome from 'react-fontawesome'
import WhiteBox from './WhiteBox'
class Component extends PureComponent {
constructor(props) {
super(props)
console.log("--- props", this.props)
this.state = {
clientId: "6233aedf-f08a-4112-9a1b-f33c3cd9b396",
clientSecret: "af85a0f0-2c68-421d-8228-a6c83628de19"
}
}
authenticateStart() {
console.error("Authenticate")
let config = Object.assign({}, this.props.serverConfig, this.state)
this.props.authenticateStart(config)
}
updateFieldHandler(field) {
return (e) => {
this.setState({
[field]: e.target.value
})
}
}
render() {
console.log("X This state", this.props)
console.log("X This state", this.state)
let authorizationEndpoint = ''
if (this.state.authorizationEndpoint) {
authorizationEndpoint = this.state.authorizationEndpoint
} else if (this.props.serverConfig) {
authorizationEndpoint = this.props.serverConfig.authorization_endpoint
}
let tokenEndpoint = ''
if (this.state.tokenEndpoint) {
tokenEndpoint = this.state.tokenEndpoint
} else if (this.props.serverConfig) {
tokenEndpoint = this.props.serverConfig.token_endpoint
}
let expanded = !!this.props.serverConfig
return (
<Panel header="OAuth Server Configuration" eventKey="2" collapsible={true} expanded={expanded}>
<form>
<h4>OAuth Authorization endpoint</h4>
<FormGroup>
<FormControl type="text" value={authorizationEndpoint} onChange={this.updateFieldHandler.bind(this)("authorizationEndpoint")} />
</FormGroup>
<h4>OAuth Token endpoint</h4>
<FormGroup>
<FormControl type="text" value={tokenEndpoint} onChange={this.updateFieldHandler.bind(this)("tokenEndpoint")} />
</FormGroup>
<h4>Client ID</h4>
<FormGroup>
<FormControl type="text" bsSize="large" value={this.state.clientId} onChange={this.updateFieldHandler.bind(this)("clientId")} />
</FormGroup>
<h4>Client secret</h4>
<FormGroup>
<FormControl type="text" bsSize="large" value={this.state.clientSecret} onChange={this.updateFieldHandler.bind(this)("clientSecret")} />
</FormGroup>
<h4>Redirect URI</h4>
<p>When you configure your client, please register the following redirect uri:</p>
<p><code>http://localhost:8080/callback</code></p>
<div>
<Button onClick={this.authenticateStart.bind(this)} bsStyle="primary">
<FontAwesome name='sign-in' /> Authenticate
</Button>
</div>
</form>
</Panel>
)
}
}
export default Component
import { connect } from 'react-redux'
import HostnameInput from '../components/HostnameInput'
import { discoveryStart } from '../actions/'
// import { discoveryStart } from '../actions/'
import API from '../utils/API'
const mapStateToProps = (state, ownProps) => (state)
const mapStateToProps = (state) => ({
serverError: state.serverError
})
const mapDispatchToProps = {
discoveryStart
discoveryStart: API.discovery,
}
const Controller = connect(
......
import { connect } from 'react-redux'
import ServerConfigInput from '../components/ServerConfigInput'
// import { discoveryStart } from '../actions/'
import API from '../utils/API'
const mapStateToProps = (state) => ({
serverConfig: state.serverConfig
})
const mapDispatchToProps = {
authenticateStart: API.authenticate,
}
const Controller = connect(
mapStateToProps,
mapDispatchToProps
)(ServerConfigInput)
export default Controller
......@@ -4,7 +4,9 @@ import React from 'react'
import ReactDOM from 'react-dom'
import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux'
import thunkMiddleware from 'redux-thunk'
// import promiseMiddleware from 'redux-promise';
import thunk from 'redux-thunk'
// import { connectRoutes } from 'redux-first-router'
// import createHistory from 'history/createBrowserHistory'
import reducers from './reducers/'
......@@ -20,19 +22,15 @@ import '../node_modules/uninett-bootstrap-theme/css/uninett.css'
import './css/style.css'
// import {packageInstallStart, packageInstallFailed} from './actions/packages'
// const history = createHistory()
// const routerSetup = connectRoutes(history, routesMap, options)
let store = createStore(
reducers,
compose(
// routerSetup.enhancer,
applyMiddleware(
// routerSetup.middleware,
thunkMiddleware,
thunk,
logger
)
)
......
......@@ -2,16 +2,26 @@ import { handleActions } from 'redux-actions';
const reducer = handleActions({
discoveryStart: (state, action) => ({
hostname: action.payload
}),
DECREMENT: (state, action) => ({
counter: state.counter - action.payload
})
discovery: {
start: (state, action) => ({
hostname: action.payload
}),
completed: (state, action) => {
if (action.error) {
return {
serverConfig: null,
serverError: action.payload
}
}
return {
serverConfig: action.payload
}
}
}
},
{
hostname: "https://auth.dataporten"
hostname: "https://auth.dataporten.no",
serverConfig: null
});
......
// import { getAllPackages, getPackage } from './actions/packages'
// import { prepareApplication, getAllApplications } from './actions/applications'
// import { login, isAuthenticated, loginAndRedirect } from './actions/auth'
const routesMap = {
HOME: '/',
// LOGIN: { path: '/login', thunk: login() },
// PACKAGES: { path: '/', thunk: getAllPackages() },
// PACKAGE: { path: '/packages/:repo/:packageName/:version', thunk: getPackage() },
// APPLICATIONS: { path: '/applications', thunk: getAllApplications(), requiresAuth: true },
// APPLICATION: { path: '/applications/:id', thunk: prepareApplication(), requiresAuth: true },
// INSTALLATION: { path: '/installation', requiresAuth: true },
}
const options = {
onBeforeChange: (dispatch, getState, action) => {
if (!routesMap.hasOwnProperty(action.type)) {
throw new Error("Cannot find routesMap for action type ", action.type)
}
const requiresAuth = routesMap[action.type].requiresAuth
window.scrollTo(0, 0)
// if (requiresAuth) {
// if (!isAuthenticated(getState())) {
// dispatch(loginAndRedirect(action))
// }
// }
}
}
export { routesMap, options }
import actions from '../actions/'
// console.error("actions", actions)
const API = {
"discovery": function(hostname) {
return dispatch => {
dispatch(actions.discovery.start(hostname))
let url = hostname + '/.well-known/openid-configuration'
let config = {"headers": {}}
// config.headers.Authorization = 'Bearer ' + token.access_token
// config.headers["original-token"] = token.access_token
config.method = "GET"
config.mode = "cors"
console.log("About to fetch", config)
return fetch(url, config).then((response) => {
if (response.ok) {
return response.json()
}
throw Error(response.statusText)
})
.then((data) => {
console.log("DATA", data)
dispatch(actions.discovery.completed(data))
})
.catch((err) => {
console.error("ERROR Fetching API Discovery", err)
dispatch(actions.discovery.completed(err))
})
}
},
"authenticate": function(config) {
return dispatch => {
console.error("About to save config", config)
dispatch(actions.serverConfig.save(config))
console.error("About to authentication")
}
}
}
export default API
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment