Skip to content
This repository was archived by the owner on Jun 7, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ dist
app/bower_components
coverage
.env
*.log
kill_ez_dev.pids
1 change: 0 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ module.exports = function (grunt) {
},
livereload: {
options: {
open: 'http://<%=hostname %>:<%=port %>',
base: [
'.tmp',
'<%= yeoman.app %>'
Expand Down
115 changes: 69 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@ intuitive API and expert support make it easy for developers to authenticate,
manage, and secure users and roles in any application.

This is the development environment for the Stormpath hosted ID Site. You can
use this repository to build the same single page application (SPA) that
Stormpath provides by default. The SPA uses Angular and Browserify and it is
built using Grunt and Yeoman.
fork this repository and use it to build the same single page application (SPA)
that Stormpath provides by default, and you can make any changes that you
require for your custom version.

If you want to build your own ID Site and are comfortable with Angular, you should
use this repository.

If you are not using Angular, you can build your own ID Site from scratch
but you will need to use [Stormpath.js][] in order to communicate with our API
from your custom ID Site application.
This default application is built with Angular and has default views and styling.
If you need to make significant changes that don't fit within this application,
you may want to use [Stormpath.js][] instead. That is a smaller library that
gives you the necessary Stormpath APIs to do user management, but does not come
with pre-built views or styling.

## Browser Support

ID Site will work in the following web browser environments:
This ID Site application will work in the following web browser environments:

* Chrome (all versions)
* Internet Explorer 10+
Expand All @@ -34,64 +33,88 @@ It is assumed that you have the following tools installed on your computer
* [Bower][]
* [Grunt][]
* [Node.JS][]
* [Localtunnel.me][]

You should clone this repository and these tasks within the repository:
**Note**: At this time, only node version `4.x` is supported.

You should clone this repository and then run this within the repository:

```sh
npm install
bower install
```

## Setup an HTTPS proxy
## Getting started with `ez_dev`

Within this repository, there's a script called `ez_dev.sh`. This will setup a complete development environment for you
to be able to work on your ID Site application.

Before we get into running the script, let's take a step back to see what `ez_dev` sets up. If you want to jump right
in, go to the [running ez_dev](#running-ez_dev) section.

A typical flow for using ID Site is the following:

1. Your make a request of the `/login` endpoint of your application in the browser.
2. Your application redirects the browser to Stormapth (api.stormpath.com/sso).
3. Stormpath redirects the browser to your ID Site, as configured in the Stormpath Admin Console.
4. The ID Site application loads in your browser and presents the login form.
5. After login or registration, your browser is directed back to the server from step 1.

Because ID Site only works with HTTPS, you will need to setup a local tunnel
which will serve your your local ID Site from a secure connection. With the
local tunnel tool you must do this:
When customizing ID Site on your local machine, you need:

> lt --port 9000
* A web server to handle steps 1 and 5
* A web server to serve the assets at step 4, that would usually be handled by Stormpath.
* SSL encryption for step 3, as required by Stormpath.

It will fetch a URL and tell you something like this:
The `ez_dev` script sets up the necessary architecture needed. The components are:

> your url is: https://wqdkeiseuj.localtunnel.me
1. `fakesp` - A web server that will handle steps 1 and 5.
2. `localtunnel.me` - A free service that sets up an HTTPS proxy from the public internet to a locally running server.
3. `grunt serve` - A locally running instance of ID Site.

You must take that URL and configure your ID Site accordingly. Please login
to the [Stormpath Admin Console][] and set these options on your ID Site
Configuration:
Once this is all running, you browser will automatically open up to: `http://localhost:8001` and you will be able to see the
updated ID Site content you are working on. Any saved changes to the ID Site content are immediately reflected in your browser
when you go to an ID Site view (such as `/login`).

| Configuration Option | Should be set to |
|----------------------------------------|-------------------------------------------------------------------------------------|
| **Domain Name** | your local tunnel URL |
| **Authorized Javascript Origin URLs** | your local tunnel URL should be in this list |
| **Authorized Redirect URLs** | the endpoint on your server application which will receive the user after ID site (read below) |
Here's a visual representation of what is setup and the flow of the requests.

## Your Service Provider (required)
![tunnel architecture][tunnel_image]

The application (typically, your server) that sends the user to ID Site is known
as the Service Provider (SP). You send the user to ID Site by constructing a
redirect URL with one of our SDKs. For example, [createIdSiteUrl()][] in our
Node.js SDK.
### Running `ez_dev`

After the user authenticates at ID Site, the user is redirected back to your
application. Your application must have a callback URL which receives the user
and validates the `jwtResponse` parameter in the URL (our SDK does this work
for you).
`ez_dev` needs to know the following:

If you haven't built your service provider we have a simple service provider
application which you can use for testing purposes, see: [Fake SP][]
1. Your Stormpath API Key ID
2. Your Stormpath API Key secret
3. Your Stormpath Application HREF

The script will look for some common environment variables and file locations in this order:

## Startup
1. If `STORMPATH_API_KEY_FILE` is set, it will get the API Key ID and API Key Secret from that file
2. If `~/.stormpath/apiKey.properties` exists, it will get the API Key ID and API Key Secret from that file
3. If `STORMPATH_APPLICATION_HREF` is set, it will use that value for the Stormpath Application to connect to

Once you have setup the environment (the steps above) you are ready to start
the development tasks. Run the following command to start the server:
If neither 1. or 2. above is met, you will be asked to provide the API Key ID and the API Key Secret to the script

> grunt serve
If 3. above is not met, you will be asked to provide the Application HREF. *Note*: You can leave this value blank if
you only have the default application (`My Application`) defined in your Stormpath tenant from when it was first setup.
If you have any other Applications defined, then you must specify the Application HREF.

This will open the application your browser. Because the application does not
have a JWT request, you will see the JWT error. At this point you should use
your service provider to redirect the user to your ID Site.
Here are a few run scenarios:

```
./ez_dev.sh # may be asked to provide additional information
```

```
# explicit settings - you will not be asked for any additional information
STORMPATH_API_KEY_FILE=~/.stormpath/apiKey.mytenant.properties \
STORMPATH_APPLICATION_HREF=https://api.stormpath.com/v1/applications/stormpathidentifier123456 \
./ez_dev.sh
```

Note: The `ez_dev` script alters the ID Site settings in your Stormpath Admin Console. When you are done working on
ID Site, it is recommended that you go back to your Admin Console and revert the `Domain Name`,
`Authorized Javascript Origin URLs`, and `Authorized Redirect URLs` settings.

## Development Process - Stormpath Tenants

Expand Down Expand Up @@ -179,7 +202,7 @@ License](http://www.apache.org/licenses/LICENSE-2.0).
[Fake SP]: https://github.com/robertjd/fakesp
[Grunt]: http://gruntjs.com
[ID Site Repository]: https://github.com/stormpath/idsite
[Localtunnel.me]: http://localtunnel.me/
[Node.JS]: http://nodejs.org
[Stormpath Admin Console]: https://api.stormpath.com
[Stormpath.js]: https://github.com/stormpath/stormpath.js
[tunnel_image]: https://github.com/stormpath/idsite-src/blob/media/docs_images/idsite_tunnel_dev.png
165 changes: 165 additions & 0 deletions ez_dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#! /bin/bash

function get_property
{
FILE=$1
PROPERTY=$2
sed '/^\#/d' $FILE | grep $PROPERTY | tail -n 1 | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
}

function wait_on_service
{
URL=$1
for i in {1..10}; do
STATUS=`curl -s -I $URL | head -n1 | cut -d$' ' -f2`
if [ "$STATUS" == "" ]; then
STATUS=0
fi
if [ $STATUS == "200" ]; then
break
fi
sleep 1
done
if [ $STATUS != "200" ]; then
echo "Unable to connect to $URL."
exit 1
fi
}



echo "Setting up..."
echo

hash npm 2>/dev/null || { echo >&2 "npm is required, but it's not installed. Install via: https://github.com/tj/n"; exit 1; }
hash bower 2>/dev/null || { echo >&2 "bower is required, but it's not installed. Install via: npm install -g bower"; exit 1; }
hash grunt 2>/dev/null || { echo >&2 "grunt is required, but it's not installed. Install via: npm install -g grunt-cli"; exit 1; }
hash curl 2> /dev/null || { echo >&2 "curl is required, but it's not installed. Install via: brew install curl (on mac)"; exit 1; }

if [ -n "${STORMPATH_API_KEY_FILE}" ]; then
STORMPATH_CLIENT_APIKEY_ID=`get_property ${STORMPATH_API_KEY_FILE} "apiKey.id"`
STORMPATH_CLIENT_APIKEY_SECRET=`get_property ${STORMPATH_API_KEY_FILE} "apiKey.secret"`
elif [ -a ~/.stormpath/apiKey.properties ]; then
STORMPATH_CLIENT_APIKEY_ID=`get_property ~/.stormpath/apiKey.properties "apiKey.id"`
STORMPATH_CLIENT_APIKEY_SECRET=`get_property ~/.stormpath/apiKey.properties "apiKey.secret"`
fi

[ -z "${STORMPATH_CLIENT_APIKEY_ID}" ] && read -e -p "Enter your Stormpath API Key ID and press [ENTER]: " STORMPATH_CLIENT_APIKEY_ID
[ -z "${STORMPATH_CLIENT_APIKEY_ID}" ] && echo "Must specify a Stormpath API Key ID" && exit 1

[ -z "${STORMPATH_CLIENT_APIKEY_SECRET}" ] && read -e -p "Enter your Stormpath API Key Secret and press [ENTER]: " STORMPATH_CLIENT_APIKEY_SECRET
[ -z "${STORMPATH_CLIENT_APIKEY_SECRET}" ] && echo "Must specify a Stormpath API Key Secret" && exit 1

[ -z "${STORMPATH_APPLICATION_HREF}" ] && read -e -p "Enter your Stormpath Application HREF and press [ENTER] (default: default Stormpath Application): " STORMPATH_APPLICATION_HREF

[ -z "${DOMAIN}" ] && DOMAIN=localhost

export STORMPATH_CLIENT_APIKEY_ID STORMPATH_CLIENT_APIKEY_SECRET STORMPATH_APPLICATION_HREF DOMAIN

echo "Executing: npm install..."
npm install

if [ $? -eq 0 ]
then
echo "Successfully ran: npm install"
else
echo "npm install failed"
fi

echo "Executing: bower install..."
bower install

if [ $? -eq 0 ]
then
echo "Successfully ran: bower install"
else
echo "bower install failed"
fi

echo "Setting up ngrok..."
cd ngrok
npm install

if [ $? -eq 0 ]
then
echo "Successfully setup ngrok"
else
echo "Failed to setup ngrok"
fi

cd ..

echo "Setting up fakesp..."
cd fakesp
npm install

if [ $? -eq 0 ]
then
echo "Successfully setup fakesp"
else
echo "Failed to setup fakesp"
fi

cd ..
echo

echo "Running fakesp..."
cd fakesp
EXPR="node server.js > ../fakesp.log 2>&1 &"
eval $EXPR
FAKESP_PID=$!
cd ..

echo "Waiting for fakesep to be available..."
wait_on_service localhost:8001

echo "Running grunt serve..."
EXPR="grunt serve > grunt_serve.log 2>&1 &"
eval $EXPR
GRUNT_SERVE_PID=$!

echo "Waiting for grunt server to be available..."
wait_on_service localhost:9000

echo "Running ngrok..."
cd ngrok
EXPR="node ngrok.js > ../ngrok.log 2>&1 &"
eval $EXPR
NGROK_PID=$!
cd ..

echo "Waiting for ngrok to be available..."
URL=""
for i in {1..10}; do
URL=`head -n1 ngrok.log`
if [[ "$URL" == *"ngrok.io"* ]]; then
break
fi
sleep 1
done
if [ "$URL" == "" ]; then
echo "Unable to connect with ngrok."
exit 1
fi
wait_on_service $URL

echo
echo "fakesp PID: $FAKESP_PID, ngrok PID: $NGROK_PID, grunt PID: $GRUNT_SERVE_PID"
echo

echo $FAKESP_PID > kill_ez_dev.pids
echo $NGROK_PID >> kill_ez_dev.pids
echo $GRUNT_SERVE_PID >> kill_ez_dev.pids

echo "Tail the logs for more information:"
echo -e "\tfakesp.log"
echo -e "\tngrok.log"
echo -e "\tgrunt_serve.log"
echo

echo "run: ./kill_ez_dev.sh to kill ez dev"
echo

echo "Launching browser..."
sleep 1
open http://localhost:8001
Loading