diff --git a/src/actions/index.js b/src/actions/index.js
index bb4af8eadefe78ba51db8f1fc25b9b20104d30a0..04fefbdcd8be7d25e7b27b6d3f3027c86d339531 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -1,4 +1,13 @@
-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
diff --git a/src/components/HostnameInput.jsx b/src/components/HostnameInput.jsx
index 763b2d358d241f81e48cd91dcdedb10d8025498c..ffd555e3d6bfce7eab74570ad605c7dc52261a06 100644
--- a/src/components/HostnameInput.jsx
+++ b/src/components/HostnameInput.jsx
@@ -1,15 +1,10 @@
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 (
+
+ Error performing OAuth Discovery
+ {this.props.serverError.toString()}
+
+ or
+ Hide error
+
+
+ )
+ }
+ return null
+ }
+
render() {
+ console.log("This state", this.props)
+ let errorMessage = null
+ if (this.props.serverError) {
+ errorMessage = (
+
+
Error performing OAuth Discovery
+
{this.props.serverError}
+
+ )
+ }
+
return (
-
+
- Fill out the hostname of your OAuth server. Will only work if your OAuth server support OAuth Discovery. If not, please enter configuration manually.
+ 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.
-
- Discovery OAuth Provider
-
+ {this.getErrorMessage()}
+
+
+ Discovery OAuth Provider
+
+
+
)
}
diff --git a/src/components/MainContent.jsx b/src/components/MainContent.jsx
index 5697fe73d64f3296c1d7a19b9962e27720064a6b..7c12f00fc0bfe457025e4b349e32162090936662 100644
--- a/src/components/MainContent.jsx
+++ b/src/components/MainContent.jsx
@@ -1,26 +1,36 @@
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 = () => (
- Play with OAuth 2.0
+ Play with OAuth 2.0
Learn more about how OAuth 2.0 works, and explore OAuth protected APIs without entering any code.
-
- Navigate the library of prepared applications, deploy and start using it within few minutes. This application platform is fully automated.
-
- Library
- My installed applications
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ServerConfigInput.jsx b/src/components/ServerConfigInput.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..efa5c743ebaf4043d1446e44a224063f06a0c315
--- /dev/null
+++ b/src/components/ServerConfigInput.jsx
@@ -0,0 +1,93 @@
+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 (
+
+
+
+ )
+ }
+
+}
+
+export default Component
diff --git a/src/containers/HostnameController.js b/src/containers/HostnameController.js
index 871be138dde9c70813ee455fa324f9c9a9b903d2..06c1cef66ce68b7bba80520dbfcd7c5d8cd2dced 100644
--- a/src/containers/HostnameController.js
+++ b/src/containers/HostnameController.js
@@ -1,11 +1,14 @@
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(
diff --git a/src/containers/ServerConfigController.js b/src/containers/ServerConfigController.js
new file mode 100644
index 0000000000000000000000000000000000000000..fa98b9727b764319d7566779dc753f9d310057e7
--- /dev/null
+++ b/src/containers/ServerConfigController.js
@@ -0,0 +1,19 @@
+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
diff --git a/src/index.js b/src/index.js
index 80bacede2e5ee43e7f19a06c1d9bfa66344631da..67b12247f4f163cfb3d50a55079c7961b659fe2c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -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
)
)
diff --git a/src/reducers/index.js b/src/reducers/index.js
index 8182d2d4360afad05ee650b512968df47d24f18b..2195f70cffc7d51999187a105c7864973dbc80e4 100644
--- a/src/reducers/index.js
+++ b/src/reducers/index.js
@@ -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
});
diff --git a/src/routesMap.js b/src/routesMap.js
deleted file mode 100644
index ea4ab4333d61e48affdd1be34fdfed18603007e8..0000000000000000000000000000000000000000
--- a/src/routesMap.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 }
diff --git a/src/utils/API.js b/src/utils/API.js
index 8b137891791fe96927ad78e64b0aad7bded08bdc..6454873ae1201022eb381825c24b38e9249e0cd1 100644
--- a/src/utils/API.js
+++ b/src/utils/API.js
@@ -1 +1,49 @@
+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