Merge branch 'projects' of https://osm.etsi.org/gerrit/osm/UI into projects
diff --git a/skyquake/framework/core/modules/api/sessions.js b/skyquake/framework/core/modules/api/sessions.js
index 1be250c..2036030 100644
--- a/skyquake/framework/core/modules/api/sessions.js
+++ b/skyquake/framework/core/modules/api/sessions.js
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -112,7 +112,10 @@
 
             req.session.authorization = authorization_header_string;
             req.session.loggedIn = true;
-
+            req.session.userdata = {
+                username: username,
+                // project: req.session.projectId
+            };
             var successMsg = 'User =>' + username + ' successfully logged in.';
             successMsg += req.session.projectId ? 'Project =>' + req.session.projectId + ' set as default.' : '';
 
@@ -139,7 +142,7 @@
     return new Promise(function(resolve, reject) {
         if (req.session && req.session.loggedIn == true) {
             req.session.projectId = req.params.projectId;
-            var successMsg = 'Added project' + projectId + ' to session' + req.sessionID;
+            var successMsg = 'Added project' + req.session.projectId + ' to session' + req.sessionID;
             console.log(successMsg);
 
             return resolve ({
diff --git a/skyquake/framework/core/modules/api/userManagementAPI.js b/skyquake/framework/core/modules/api/userManagementAPI.js
index e88a5dc..0608c5d 100644
--- a/skyquake/framework/core/modules/api/userManagementAPI.js
+++ b/skyquake/framework/core/modules/api/userManagementAPI.js
@@ -33,7 +33,7 @@
     return new Promise(function(resolve, reject) {
         Promise.all([
             rp({
-                uri: utils.confdPort(api_server) + '/api/operational/user-config/users',
+                uri: utils.confdPort(api_server) + '/api/operational/user-config/user',
                 method: 'GET',
                 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
                     'Authorization': req.session && req.session.authorization
@@ -46,7 +46,7 @@
             var response = {};
             response['data'] = {};
             if (result[0].body) {
-                response['data']['users'] = JSON.parse(result[0].body)['rw-user:users'];
+                response['data']['user'] = JSON.parse(result[0].body)['rw-user:user'];
             }
             response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
 
@@ -62,12 +62,27 @@
         });
     });
 };
+
+UserManagement.getProfile = function(req) {
+    var self = this;
+    var api_server = req.query['api_server'];
+    return new Promise(function(resolve, reject) {
+        var response = {};
+            response['data'] = {
+            userId: req.session.userdata.username,
+            projectId: req.session.projectId
+        };
+        response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+        resolve(response);
+    });
+};
 UserManagement.create = function(req) {
     var self = this;
     var api_server = req.query['api_server'];
     var data = req.body;
     data = {
-        "users":[data]
+        "user":[data]
     }
     return new Promise(function(resolve, reject) {
         Promise.all([
@@ -107,7 +122,7 @@
     var api_server = req.query['api_server'];
     var bodyData = req.body;
     data = {
-        "users":[bodyData]
+        "user":[bodyData]
     }
     var updateTasks = [];
     if(bodyData.hasOwnProperty('old-password')) {
@@ -174,7 +189,7 @@
     var domain = req.params.domain;
     var api_server = req.query["api_server"];
     var requestHeaders = {};
-    var url = `${utils.confdPort(api_server)}/api/config/user-config/users/${username},${domain}`
+    var url = `${utils.confdPort(api_server)}/api/config/user-config/user/${username},${domain}`
     return new Promise(function(resolve, reject) {
         _.extend(requestHeaders,
             constants.HTTP_HEADERS.accept.data,
diff --git a/skyquake/framework/core/modules/routes/userManagement.js b/skyquake/framework/core/modules/routes/userManagement.js
index 11fb8b1..4e272d0 100644
--- a/skyquake/framework/core/modules/routes/userManagement.js
+++ b/skyquake/framework/core/modules/routes/userManagement.js
@@ -43,6 +43,13 @@
         utils.sendErrorResponse(error, res);
     });
 });
+Router.get('/user-profile', cors(), function(req, res) {
+    UserManagementAPI.getProfile(req).then(function(response) {
+        utils.sendSuccessResponse(response, res);
+    }, function(error) {
+        utils.sendErrorResponse(error, res);
+    });
+});
 Router.post('/user', cors(), function(req, res) {
     UserManagementAPI.create(req).then(function(response) {
         utils.sendSuccessResponse(response, res);
diff --git a/skyquake/framework/widgets/form_controls/selectOption.jsx b/skyquake/framework/widgets/form_controls/selectOption.jsx
index 1e02f15..397963e 100644
--- a/skyquake/framework/widgets/form_controls/selectOption.jsx
+++ b/skyquake/framework/widgets/form_controls/selectOption.jsx
@@ -28,7 +28,7 @@
   render() {
     let html;
     let defaultValue = this.props.defaultValue;
-    let options =  this.props.options.map(function(op, i) {
+    let options =  this.props.options && this.props.options.map(function(op, i) {
     let value;
     let label;
     if(typeof(op) == 'object') {
@@ -40,12 +40,12 @@
     }
 
       return <option key={i} value={JSON.stringify(value)}>{label}</option>
-    });
+    }) || [];
     if (this.props.initial) {
       options.unshift(<option key='blank' value={JSON.stringify(this.props.defaultValue)}></option>);
     }
     html = (
-        <label key={this.props.key}>
+        <label key={this.props.key} className={this.props.className}>
             {this.props.label}
             {
               this.props.readonly ? defaultValue
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeApp.scss b/skyquake/framework/widgets/skyquake_container/skyquakeApp.scss
index 77e72cf..b2493a3 100644
--- a/skyquake/framework/widgets/skyquake_container/skyquakeApp.scss
+++ b/skyquake/framework/widgets/skyquake_container/skyquakeApp.scss
@@ -16,95 +16,7 @@
     h1 {
         text-transform: uppercase;
     }
-    .active {
-        background-color: $brand-blue!important;
-        border-color: $brand-blue!important;
-        color: #fff!important
-    }
-    .skyquakeNav {
-        display: -ms-flexbox;
-        display: flex;
-        color:white;
-        background:black;
-        position:relative;
-        z-index: 10;
-        font-size:0.75rem;
-        .secondaryNav {
-            -ms-flex: 1 1 auto;
-                flex: 1 1 auto;
-            display: -ms-flexbox;
-            display: flex;
-            -ms-flex-pack: end;
-                justify-content: flex-end;
-        }
-        .app {
-            position:relative;
-            h2 {
-                font-size:0.75rem;
-                border-right: 1px solid black;
-                display: -ms-flexbox;
-                display: flex;
-                -ms-flex-align: center;
-                    align-items: center;
-                .oi {
-                    padding-right: 0.5rem;
-                }
-            }
-            .menu {
-                position:absolute;
-                display:none;
-                z-index:2;
-                width: 100%;
-            }
-            &:first-child{
-                h2 {
-                    border-left: 1px solid black;
-                }
-            }
-            &:hover {
-                a {
-                    color:$brand-blue-light;
-                    cursor:pointer;
-                }
-                .menu {
-                    display:block;
-                    background:black;
-                    a {
-                        color:white;
-                    }
-                    li:hover {
-                        a {
-                            color:$brand-blue-light;
-                        }
-                    }
-                }
-            }
-            &.active {
-                color:white;
-                background:black;
-                a {
-                    color:white;
-                }
-            }
-        }
-        a{
-            display:block;
-            padding:0.5rem 1rem;
-            text-decoration:none;
-            text-transform:uppercase;
-            color:white;
-        }
-        &:before {
-            content: '';
-            height:1.85rem;
-            width:5.5rem;
-            /*margin:0 1rem;*/
-            /*padding:0 0.125rem;*/
-            /*background: url('../../style/img/svg/riftio_logo_white.svg') no-repeat center center;*/
-            background: url('../../style/img/svg/osm-logo_color_rgb_white_text.svg') no-repeat center center;
-            background-size: contain;
-        }
-    }
+
     .skyquakeContainerWrapper {
     }
     .titleBar {
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx b/skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx
index 558cc62..9d60183 100644
--- a/skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx
+++ b/skyquake/framework/widgets/skyquake_container/skyquakeContainer.jsx
@@ -18,7 +18,7 @@
 import React from 'react';
 import AltContainer from 'alt-container';
 import Alt from './skyquakeAltInstance.js';
-import SkyquakeNav from './skyquakeNav.jsx';
+import SkyquakeNav from '../skyquake_nav/skyquakeNav.jsx';
 import EventCenter from './eventCenter.jsx';
 import SkyquakeContainerActions from './skyquakeContainerActions.js'
 import SkyquakeContainerStore from './skyquakeContainerStore.js';
@@ -85,7 +85,7 @@
     render() {
         const {displayNotification, notificationMessage, displayScreenLoader, notificationType, ...state} = this.state;
         var html;
-
+        let nav = _.cloneDeep(this.state.nav);
         if (this.matchesLoginUrl()) {
             html = (
                 <AltContainer>
@@ -109,9 +109,12 @@
                             onDismiss={SkyquakeContainerActions.hideNotification}
                         />
                         <ScreenLoader show={displayScreenLoader}/>
-                        <SkyquakeNav nav={this.state.nav}
-                            currentPlugin={this.state.currentPlugin}
-                            store={SkyquakeContainerStore} />
+                        <SkyquakeNav nav={nav}
+                            currentPlugin={this.state.user.currentPlugin}
+                            currentUser={this.state.user.userId}
+                            currentProject={this.state.user.projectId}
+                            store={SkyquakeContainerStore}
+                            projects={this.state.projects} />
                         <div className="titleBar">
                             <h1>{(this.state.nav.name ? this.state.nav.name.replace('_', ' ').replace('-', ' ') : this.state.currentPlugin && this.state.currentPlugin.replace('_', ' ').replace('-', ' ')) + tag}</h1>
                         </div>
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js
index 773978b..ed97f0c 100644
--- a/skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js
+++ b/skyquake/framework/widgets/skyquake_container/skyquakeContainerActions.js
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,5 +29,8 @@
     'hideNotification',
     //Screen Loader
     'showScreenLoader',
-    'hideScreenLoader'
+    'hideScreenLoader',
+    'openProjectSocketSuccess',
+    'getUserProfileSuccess',
+    'selectActiveProjectSuccess'
 );
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js
index ae2147a..a26de2b 100644
--- a/skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js
+++ b/skyquake/framework/widgets/skyquake_container/skyquakeContainerSource.js
@@ -113,6 +113,84 @@
             success: SkyquakeContainerActions.openNotificationsSocketSuccess,
             error: SkyquakeContainerActions.openNotificationsSocketError
         }
+    },
+    openProjectSocket() {
+            return {
+                remote: function(state) {
+                    return new Promise(function(resolve, reject) {
+                        //If socket connection already exists, eat the request.
+                        if(state.socket) {
+                            return resolve(false);
+                        }
+                        $.ajax({
+                            url: '/socket-polling',
+                            type: 'POST',
+                            beforeSend: Utils.addAuthorizationStub,
+                            data: {
+                                url: '/project?api_server=' + API_SERVER
+                            },
+                            success: function(data, textStatus, jqXHR) {
+                                Utils.checkAndResolveSocketRequest(data, resolve, reject);
+                            }
+                            })
+                        .fail(function(xhr){
+                            //Authentication and the handling of fail states should be wrapped up into a connection class.
+                            Utils.checkAuthentication(xhr.status);
+                        });;
+                    });
+                },
+            success: SkyquakeContainerActions.openProjectSocketSuccess
+        }
+    },
+
+    getUserProfile() {
+        return {
+            remote: function(state, recordID) {
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: '/user-profile?api_server=' + API_SERVER,
+                        type: 'GET',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(data);
+                        }
+                    }).fail(function(xhr) {
+                        //Authentication and the handling of fail states should be wrapped up into a connection class.
+                        Utils.checkAuthentication(xhr.status);
+                    });;
+                });
+            },
+            loading: Alt.actions.global.showScreenLoader,
+            success: SkyquakeContainerActions.getUserProfileSuccess
+        }
+    },
+
+    selectActiveProject() {
+        return {
+            remote: function(state, event) {
+                let projectId;
+                try {
+                    projectId = JSON.parse(JSON.parse(event.currentTarget.value));
+                } catch(e) {
+                    console.log('Something went wrong in the selectActiveProject source function', e);
+                }
+
+                return new Promise(function(resolve, reject) {
+                    $.ajax({
+                        url: `/session/${projectId}?api_server=${API_SERVER}`,
+                        type: 'PUT',
+                        beforeSend: Utils.addAuthorizationStub,
+                        success: function(data) {
+                            resolve(projectId);
+                        }
+                    }).fail(function(xhr) {
+                        //Authentication and the handling of fail states should be wrapped up into a connection class.
+                        Utils.checkAuthentication(xhr.status);
+                    });;
+                });
+            },
+            success: SkyquakeContainerActions.selectActiveProjectSuccess
+        }
     }
 }
 
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js
index d1a8a9e..1403d0a 100644
--- a/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js
+++ b/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js
@@ -20,6 +20,7 @@
 import Alt from './skyquakeAltInstance.js';
 import SkyquakeContainerSource from './skyquakeContainerSource.js';
 import SkyquakeContainerActions from './skyquakeContainerActions';
+let Utils = require('utils/utils.js');
 import _ from 'lodash';
 //Temporary, until api server is on same port as webserver
 var rw = require('utils/rw.js');
@@ -32,6 +33,8 @@
         this.nav = {};
         this.notifications = [];
         this.socket = null;
+        this.projects = [];
+        this.user = {};
         //Notification defaults
         this.notificationMessage = '';
         this.displayNotification = false;
@@ -161,6 +164,39 @@
         })
     }
 
+    openProjectSocketSuccess = (connection) => {
+        var self = this;
+        var ws = window.multiplexer.channel(connection);
+        if (!connection) return;
+        self.setState({
+            socket: ws.ws,
+            channelId: connection
+        });
+        ws.onmessage = function(socket) {
+            try {
+                var data = JSON.parse(socket.data);
+                Utils.checkAuthentication(data.statusCode, function() {
+                    self.closeSocket();
+                });
+                if (!_.isEqual(data.project, self.projects)) {
+                    self.setState({
+                        projects: data.project
+                    });
+                }
+            } catch(e) {
+                console.log('HIT an exception in openProjectSocketSuccess', e);
+            }
+        };
+    }
+    getUserProfileSuccess = (user) => {
+        this.alt.actions.global.hideScreenLoader.defer();
+        this.setState({user})
+    }
+    selectActiveProjectSuccess = (projectId) => {
+        let user = this.user;
+        user.projectId = projectId;
+        this.setState({user});
+        }
     //Notifications
     showNotification = (data) => {
         let state = {
@@ -172,7 +208,8 @@
         if(typeof(data) == 'string') {
 
         } else {
-            state.notificationMessage = data.msg;
+            if(!data) data = {};
+            state.notificationMessage = data.msg || 'Something very bad happened wrong';
             if(data.type) {
                 state.notificationType = data.type;
             }
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx b/skyquake/framework/widgets/skyquake_nav/skyquakeNav.jsx
similarity index 72%
rename from skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx
rename to skyquake/framework/widgets/skyquake_nav/skyquakeNav.jsx
index 73a2f02..a61ee54 100644
--- a/skyquake/framework/widgets/skyquake_container/skyquakeNav.jsx
+++ b/skyquake/framework/widgets/skyquake_nav/skyquakeNav.jsx
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +22,10 @@
 import Crouton from 'react-crouton';
 import 'style/common.scss';
 
+import './skyquakeNav.scss';
+import SelectOption from '../form_controls/selectOption.jsx';
+import {FormSection} from '../form_controls/formControls.jsx';
+
 //Temporary, until api server is on same port as webserver
 var rw = require('utils/rw.js');
 var API_SERVER = rw.getSearchParams(window.location).api_server;
@@ -48,6 +52,75 @@
     }
 }
 
+class SelectProject extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    selectProject(e) {
+        let value = JSON.parse(e.currentTarget.value);
+        console.log('selected project', value)
+    }
+    render() {
+        let props = this.props;
+        let currentValue = JSON.stringify(props.currentProject);
+        let projects = this.props.projects.map((p,i) => {
+            return {
+                label: p.name,
+                value: p.name
+            }
+        });
+        return (
+            <div className="userSection app">
+                Project:
+                <SelectOption
+                    options={projects}
+                    value={currentValue}
+                    defaultValue={currentValue}
+                    onChange={props.onSelectProject}
+                    className="projectSelect" />
+            </div>
+        )
+    }
+}
+
+class UserNav extends React.Component {
+    constructor(props) {
+        super(props);
+    }
+    handleLogout() {
+        Utils.clearAuthentication();
+    }
+    selectProject(e) {
+        let value = JSON.parse(e.currentTarget.value)
+        console.log('selected project', value)
+    }
+    render() {
+        let props = this.props;
+        return (
+            <div className="app">
+                <h2>
+                    <a>
+                        {props.currentUser}
+                    </a>
+                    <span className="oi" data-glyph="caret-bottom"></span>
+                </h2>
+                <ul className="menu">
+                    <li>
+                        <a onClick={this.handleLogout}>
+                            Logout
+                        </a>
+                    </li>
+                </ul>
+            </div>
+        )
+    }
+}
+
+UserNav.defaultProps = {
+    projects: [
+
+    ]
+}
 
 //
 // Exported classes and functions
@@ -64,6 +137,10 @@
         this.state.validateErrorEvent = 0;
         this.state.validateErrorMsg = '';
     }
+    componentDidMount() {
+        this.props.store.openProjectSocket();
+        this.props.store.getUserProfile();
+    }
     validateError = (msg) => {
         this.setState({
             validateErrorEvent: true,
@@ -90,7 +167,7 @@
                 <div>
                 {this.returnCrouton()}
             <nav className="skyquakeNav">
-                {buildNav.call(this, this.props.nav, this.props.currentPlugin)}
+                {buildNav.call(this, this.props.nav, this.props.currentPlugin, this.props)}
             </nav>
 
             </div>
@@ -156,12 +233,15 @@
     return ref;
 }
 
+
+
+
 /**
  * Constructs nav for each plugin, along with available subnavs
  * @param  {array} nav List returned from /nav endpoint.
  * @return {array}     List of constructed nav element for each plugin
  */
-export function buildNav(nav, currentPlugin) {
+export function buildNav(nav, currentPlugin, props) {
     let navList = [];
     let navListHTML = [];
     let secondaryNav = [];
@@ -169,8 +249,13 @@
     self.hasSubNav = {};
     let secondaryNavHTML = (
         <div className="secondaryNav" key="secondaryNav">
-        {secondaryNav}
-            <LogoutAppMenuItem />
+            {secondaryNav}
+            <SelectProject
+                onSelectProject={props.store.selectActiveProject}
+                projects={props.projects}
+                currentProject={props.currentProject} />
+            <UserNav
+                currentUser={props.currentUser}  />
         </div>
     )
     for (let k in nav) {
diff --git a/skyquake/framework/widgets/skyquake_nav/skyquakeNav.scss b/skyquake/framework/widgets/skyquake_nav/skyquakeNav.scss
new file mode 100644
index 0000000..f15af7b
--- /dev/null
+++ b/skyquake/framework/widgets/skyquake_nav/skyquakeNav.scss
@@ -0,0 +1,104 @@
+@import '../../style/_colors.scss';
+.active {
+        background-color: $brand-blue!important;
+        border-color: $brand-blue!important;
+        color: #fff!important
+    }
+    .skyquakeNav {
+        display: -ms-flexbox;
+        display: flex;
+        color:white;
+        background:black;
+        position:relative;
+        z-index: 10;
+        font-size:0.75rem;
+        padding-right:1rem;
+        .secondaryNav {
+            -ms-flex: 1 1 auto;
+                flex: 1 1 auto;
+            display: -ms-flexbox;
+            display: flex;
+            -ms-flex-pack: end;
+                justify-content: flex-end;
+        }
+        .app {
+            position:relative;
+            margin:auto;
+            h2 {
+                font-size:0.75rem;
+                border-right: 1px solid black;
+                display: -ms-flexbox;
+                display: flex;
+                -ms-flex-align: center;
+                    align-items: center;
+                .oi {
+                    padding-right: 0.5rem;
+                }
+            }
+            .menu {
+                position:absolute;
+                display:none;
+                z-index:2;
+                width: 100%;
+            }
+            &:first-child{
+                h2 {
+                    border-left: 1px solid black;
+                }
+            }
+            &:hover {
+                a {
+                    color:$brand-blue-light;
+                    cursor:pointer;
+                }
+                .menu {
+                    display:block;
+                    background:black;
+                    a {
+                        color:white;
+                    }
+                    li:hover {
+                        a {
+                            color:$brand-blue-light;
+                        }
+                    }
+                }
+            }
+            &.active {
+                color:white;
+                background:black;
+                a {
+                    color:white;
+                }
+            }
+        }
+        a{
+            display:block;
+            padding:0.5rem 1rem;
+            text-decoration:none;
+            text-transform:uppercase;
+            color:white;
+        }
+        &:before {
+            content: '';
+            min-width: 5.5rem;
+            margin: 0.125rem 1rem;
+            background: url('../../style/img/svg/osm-logo_color_rgb_white_text.svg') no-repeat center center;
+            background-size: contain;
+        }
+        .userSection {
+            display:-ms-flexbox;
+            display:flex;
+            -ms-flex-align:center;
+            align-items:center;
+            padding-left: 1rem;
+            text-transform:uppercase;
+            border-left:1px solid white;
+            .projectSelect {
+                padding: 0 0.5rem;
+                font-size: 1rem;
+                /* min-width: 75%;*/
+                height: 25px;
+            }
+        }
+    }
diff --git a/skyquake/plugins/project_management/src/dashboard/dashboard.jsx b/skyquake/plugins/project_management/src/dashboard/dashboard.jsx
index 71921a7..8cda802 100644
--- a/skyquake/plugins/project_management/src/dashboard/dashboard.jsx
+++ b/skyquake/plugins/project_management/src/dashboard/dashboard.jsx
@@ -94,9 +94,10 @@
         let self = this;
         e.preventDefault();
         e.stopPropagation();
-        let projectUsers = self.state.projectUsers;
-        let cleanUsers = this.cleanUsers(projectUsers);
         let projectName = self.state['name'];
+        let projectUsers = self.state.projectUsers;
+        let cleanUsers = this.cleanUsers(projectUsers, projectName);
+
 
         this.Store.createProject({
             'name': projectName,
@@ -111,9 +112,10 @@
         let self = this;
         e.preventDefault();
         e.stopPropagation();
+         let projectName = self.state['name'];
         let projectUsers = self.state.projectUsers;
-        let cleanUsers = this.cleanUsers(projectUsers);
-        let projectName = self.state['name'];
+        let cleanUsers = this.cleanUsers(projectUsers, projectName);
+
 
         this.Store.updateProject(_.merge({
             'name': projectName,
@@ -124,7 +126,7 @@
             }
         }));
     }
-    cleanUsers(projectUsers) {
+    cleanUsers(projectUsers, projectName) {
         let cleanUsers = [];
         //Remove null values from role
         projectUsers.map((u) => {
@@ -132,8 +134,10 @@
            u.role && u.role.map((r,i) => {
              let role = {};
              //you may add a user without a role or a keys, but if one is present then the other must be as well.
-            if(!r.role || ( !r || ((r.role || r['keys']) && (!r.role || !r['keys'])))) {
+            if(!r.role ) {
             } else {
+                delete r.keys;
+                    // r.keys = projectName;
                     cleanRoles.push(r)
             }
            });
diff --git a/skyquake/plugins/project_management/src/dashboard/projectMgmtSource.js b/skyquake/plugins/project_management/src/dashboard/projectMgmtSource.js
index ce0c984..55646e8 100644
--- a/skyquake/plugins/project_management/src/dashboard/projectMgmtSource.js
+++ b/skyquake/plugins/project_management/src/dashboard/projectMgmtSource.js
@@ -25,11 +25,16 @@
                   type: 'GET',
                   beforeSend: Utils.addAuthorizationStub,
                   success: function(data, textStatus, jqXHR) {
-                    resolve(data.users);
+                    resolve(data.user);
                   }
                 }).fail(function(xhr){
                   //Authentication and the handling of fail states should be wrapped up into a connection class.
                   Utils.checkAuthentication(xhr.status);
+                  let msg = xhr.responseText;
+                  if(xhr.errorMessage) {
+                    msg = xhr.errorMessage
+                  }
+                  reject(msg);
                 });
               });
           },
@@ -53,6 +58,11 @@
                 }).fail(function(xhr){
                   //Authentication and the handling of fail states should be wrapped up into a connection class.
                   Utils.checkAuthentication(xhr.status);
+                  let msg = xhr.responseText;
+                  if(xhr.errorMessage) {
+                    msg = xhr.errorMessage
+                  }
+                  reject(msg);
                 });
               });
           },
@@ -77,6 +87,11 @@
                 }).fail(function(xhr){
                   //Authentication and the handling of fail states should be wrapped up into a connection class.
                   Utils.checkAuthentication(xhr.status);
+                  let msg = xhr.responseText;
+                  if(xhr.errorMessage) {
+                    msg = xhr.errorMessage
+                  }
+                  reject(msg);
                 });
             });
           },
@@ -100,6 +115,11 @@
               }).fail(function(xhr){
                 //Authentication and the handling of fail states should be wrapped up into a connection class.
                 Utils.checkAuthentication(xhr.status);
+                let msg = xhr.responseText;
+                if(xhr.errorMessage) {
+                  msg = xhr.errorMessage
+                }
+                reject(msg);
               });
             });
           },
@@ -125,6 +145,11 @@
                 }).fail(function(xhr){
                   //Authentication and the handling of fail states should be wrapped up into a connection class.
                   Utils.checkAuthentication(xhr.status);
+                  let msg = xhr.responseText;
+                  if(xhr.errorMessage) {
+                    msg = xhr.errorMessage
+                  }
+                  reject(msg);
                 });
               });
             },
diff --git a/skyquake/plugins/project_management/src/dashboard/projectMgmtStore.js b/skyquake/plugins/project_management/src/dashboard/projectMgmtStore.js
index 1cb2088..17a5a59 100644
--- a/skyquake/plugins/project_management/src/dashboard/projectMgmtStore.js
+++ b/skyquake/plugins/project_management/src/dashboard/projectMgmtStore.js
@@ -15,7 +15,7 @@
         this.projectUsers = [];
         this.selectedUser = null;
         this.selectedRole = null;
-        this.roles = ['rw-rbac-platform:platform-admin', 'rw-rbac-platform:platform-oper', 'rw-rbac-platform:super-admin'
+        this.roles = ['rw-project:project-admin', 'rw-project:project-oper', 'rw-project:project-create'
         // ,'some_other_role', 'yet_another_role', 'operator_role', 'some_other_role', 'yet_another_role'
         ];
         this.users = [];
@@ -147,17 +147,17 @@
         });
     }
     handleAddUser(e) {
+        let self = this;
         let u = JSON.parse(this.selectedUser);
         let r = this.selectedRole;
         let projectUsers = this.projectUsers;
-        let keys = ',';
         console.log('adding user')
         projectUsers.push({
           'user-name': u['user-name'],
           'user-domain': u['user-domain'],
           "role":[{
                       "role": r,
-                      "keys": keys
+                      "keys": self.name
             }
           ]
         })
@@ -168,16 +168,14 @@
         let {userIndex, roleIndex, checked} = data;
         let projectUsers = this.projectUsers;
         let selectedRole = self.roles[roleIndex];
-        let keys = ',';
         if(checked) {
             if(!projectUsers[userIndex].role) projectUsers[userIndex].role = [];
             projectUsers[userIndex].role.push({
-                role: self.roles[roleIndex],
-                keys: keys
+                role: self.roles[roleIndex]
             })
         } else {
             let role = projectUsers[userIndex].role;
-            let roleIndex = _.findIndex(role, {role:selectedRole, keys: keys})
+            let roleIndex = _.findIndex(role, {role:selectedRole})
             projectUsers[userIndex].role.splice(roleIndex, 1)
         }
        self.setState({projectUsers});
@@ -186,9 +184,7 @@
     handleUpdateUserRoleInProject(data) {
         let {userIndex, roleIndex, value} = data;
         let projectUsers = this.projectUsers;
-        let keys = ',';
         projectUsers[userIndex].role[roleIndex].role = value;
-        projectUsers[userIndex].role[roleIndex]['keys'] = keys;
 
     }
     addRoleToUserInProject(userIndex) {
@@ -196,11 +192,8 @@
         if(!projectUsers[userIndex].role) {
             projectUsers[userIndex].role = [];
         }
-        let keys = ',';
         projectUsers[userIndex].role.push({
-              'role': null,
-              //temp until we get actual keys
-              'keys' : keys
+              'role': null
             });
         this.setState({
             projectUsers
diff --git a/skyquake/plugins/user_management/src/dashboard/dashboard.jsx b/skyquake/plugins/user_management/src/dashboard/dashboard.jsx
index 0275831..f946cbb 100644
--- a/skyquake/plugins/user_management/src/dashboard/dashboard.jsx
+++ b/skyquake/plugins/user_management/src/dashboard/dashboard.jsx
@@ -79,7 +79,7 @@
     cancelEditUser = () => {
         this.actions.editUser(true)
     }
-    closePanel = () => {
+    osePanel = () => {
         this.actions.handleCloseUserPanel();
     }
     // updateUser = (e) => {
diff --git a/skyquake/plugins/user_management/src/dashboard/userMgmtSource.js b/skyquake/plugins/user_management/src/dashboard/userMgmtSource.js
index a5c6242..267387a 100644
--- a/skyquake/plugins/user_management/src/dashboard/userMgmtSource.js
+++ b/skyquake/plugins/user_management/src/dashboard/userMgmtSource.js
@@ -25,7 +25,7 @@
                   type: 'GET',
                   beforeSend: Utils.addAuthorizationStub,
                   success: function(data, textStatus, jqXHR) {
-                    resolve(data.users);
+                    resolve(data.user);
                   }
                 }).fail(function(xhr){
                   //Authentication and the handling of fail states should be wrapped up into a connection class.
@@ -42,7 +42,7 @@
             'error': 'There was an error retrieving the resource orchestrator information.'
           }),
           success: Alt.actions.global.getUsersSuccess,
-                    loading: Alt.actions.global.showScreenLoader,
+          loading: Alt.actions.global.showScreenLoader,
           error: Alt.actions.global.showNotification
         },
         updateUser: {
diff --git a/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementSource.js b/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementSource.js
index ad6e818..2e1f3c0 100644
--- a/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementSource.js
+++ b/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementSource.js
@@ -25,7 +25,7 @@
                   type: 'GET',
                   beforeSend: Utils.addAuthorizationStub,
                   success: function(data, textStatus, jqXHR) {
-                    resolve(data.users);
+                    resolve(data.user);
                   }
                 }).fail(function(xhr){
                   //Authentication and the handling of fail states should be wrapped up into a connection class.
diff --git a/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementStore.js b/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementStore.js
index 38dd1ce..326f13a 100644
--- a/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementStore.js
+++ b/skyquake/plugins/user_management/src/platformRoleManagement/platformRoleManagementStore.js
@@ -150,14 +150,12 @@
         let u = JSON.parse(this.selectedUser);
         let r = this.selectedRole;
         let platformUsers = this.platformUsers;
-        let keys = ","
         console.log('adding user')
         platformUsers.push({
           'user-name': u['user-name'],
           'user-domain': u['user-domain'],
           "role":[{
-                      "role": r,
-                      "keys": keys
+                      "role": r
             }
           ]
         })
@@ -168,16 +166,13 @@
         let {userIndex, roleIndex, checked} = data;
         let platformUsers = this.platformUsers;
         let selectedRole = self.roles[roleIndex];
-        let keys = ","
         if(checked) {
             if(!platformUsers[userIndex].role) platformUsers[userIndex].role = [];
             platformUsers[userIndex].role.push({
-                role: selectedRole,
-                keys: keys
+                role: selectedRole
             })
         } else {
             let role = platformUsers[userIndex].role;
-            let roleIndex = _.findIndex(role, {role:selectedRole, keys: keys})
             platformUsers[userIndex].role.splice(roleIndex, 1)
         }
        self.setState({platformUsers});
@@ -187,7 +182,6 @@
         let {userIndex, roleIndex, value} = data;
         let platformUsers = this.platformUsers;
         platformUsers[userIndex].role[roleIndex].role = value;
-        platformUsers[userIndex].role[roleIndex]['keys'] = value;
 
     }
     addRoleToUserInProject(userIndex) {
@@ -196,9 +190,7 @@
             platformUsers[userIndex].role = [];
         }
         platformUsers[userIndex].role.push({
-              'role': null,
-              //temp until we get actual keys
-              'keys' : ','
+              'role': null
             });
         this.setState({
             platformUsers