.DS_Store/
.DS_Store
+._.DS_Store
err.log
out.log
node_modules/
npm-debug.log
fixtures/
.build
+.fuse_*
--- /dev/null
+#!/usr/bin/env bash
+#
+# Copyright 2016,2017 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author(s): Jeremy Mordkoff, Lezz Giles
+# Creation Date: 08/29/2016
+#
+#
+
+# BUILD.sh
+#
+# This is a top-level build script for OSM SO or UI
+#
+# Arguments and options: use -h or --help
+#
+# dependencies -- requires sudo rights
+
+MODULE=UI
+
+# Defensive bash programming flags
+set -o errexit # Exit on any error
+trap 'echo ERROR: Command failed: \"$BASH_COMMAND\"' ERR
+set -o nounset # Expanding an unset variable is an error. Variables must be
+ # set before they can be used.
+
+###############################################################################
+# Options and arguments
+
+# There
+params="$(getopt -o h -l install,help --name "$0" -- "$@")"
+if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
+
+eval set -- $params
+
+installFromPackages=false
+
+while true; do
+ case "$1" in
+ --install) installFromPackages=true; shift;;
+ -h|--help)
+ echo
+ echo "NAME:"
+ echo " $0"
+ echo
+ echo "SYNOPSIS:"
+ echo " $0 -h|--help"
+ echo " $0 [--install] [PLATFORM_REPOSITORY] [PLATFORM_VERSION]"
+ echo
+ echo "DESCRIPTION:"
+ echo " Prepare current system to run $MODULE. By default, the system"
+ echo " is set up to support building $MODULE; optionally, "
+ echo " $MODULE can be installed from a Debian package repository."
+ echo
+ echo " --install: install $MODULE from package"
+ echo " PLATFORM_REPOSITORY (optional): name of the RIFT.ware repository."
+ echo " PLATFORM_VERSION (optional): version of the platform packages to be installed."
+ echo
+ exit 0;;
+ --) shift; break;;
+ *) echo "Not implemented: $1" >&2; exit 1;;
+ esac
+done
+
+# Turn this on after handling options, so the output doesn't get cluttered.
+set -x # Print commands before executing them
+
+###############################################################################
+# Set up repo and version
+
+PLATFORM_REPOSITORY=${1:-osm-rbac}
+PLATFORM_VERSION=${2:-5.1.3.9999.70283}
+
+###############################################################################
+# Main block
+
+# must be run from the top of a workspace
+cd $(dirname $0)
+
+# enable the right repos
+curl http://repos.riftio.com/public/xenial-riftware-public-key | sudo apt-key add -
+
+# always use the same file name so that updates will overwrite rather than enable a second repo
+sudo curl -o /etc/apt/sources.list.d/rift.list http://buildtracker.riftio.com/repo_file/ub16/${PLATFORM_REPOSITORY}/
+sudo apt-get update
+
+sudo apt install -y --allow-downgrades rw.tools-container-tools=${PLATFORM_VERSION} rw.tools-scripts=${PLATFORM_VERSION}
+
+if $installFromPackages; then
+
+ # Install module and platform from packages
+ sudo -H /usr/rift/container_tools/mkcontainer --modes $MODULE --repo ${PLATFORM_REPOSITORY} --rw-version ${PLATFORM_VERSION}
+
+else
+
+ # Install environment to build module
+ sudo -H /usr/rift/container_tools/mkcontainer --modes $MODULE-dev --repo ${PLATFORM_REPOSITORY} --rw-version ${PLATFORM_VERSION}
+
+ # Build and install module
+ make -j16
+ sudo make install
+
+fi
+
+if [[ $MODULE == SO ]]; then
+ echo "Creating Service ...."
+ sudo /usr/rift/bin/create_launchpad_service
+fi
+
+
# DO NOT add any code before this and DO NOT
# include this file anywhere else
##
-include(rift_submodule)
+include(rift_submodule NO_POLICY_SCOPE)
##
# Submodule specific includes will go here,
${subdirs}
)
+##
+# Only skyquake package contains anything
+##
+rift_set_component_package_fields(
+ skyquake
+ DESCRIPTION "RIFT.ware UI"
+ POST_INSTALL_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/postinst"
+ )
+
##
# This macro adds targets for documentaion, unittests, code coverage and packaging
##
FROM ubuntu:16.04
-RUN apt-get update && apt-get -y install python3 curl build-essential
+RUN apt-get update && apt-get -y install python3 curl build-essential apt-transport-https sudo
RUN curl http://repos.riftio.com/public/xenial-riftware-public-key | apt-key add - && \
- curl -o /etc/apt/sources.list.d/OSM.list http://buildtracker.riftio.com/repo_file/ub16/OSM/ && \
+ curl -o /etc/apt/sources.list.d/rift.list http://buildtracker.riftio.com/repo_file/ub16/OSM/ && \
apt-get update && \
- apt-get -y install rw.toolchain-rwbase \
- rw.toolchain-rwtoolchain \
- rw.core.mgmt-mgmt \
- rw.core.util-util \
- rw.core.rwvx-rwvx \
- rw.core.rwvx-rwdts \
- rw.automation.core-RWAUTO \
- rw.tools-container-tools \
- rw.tools-scripts \
- python-cinderclient \
- libxml2-dev \
- libxslt-dev
+ apt-get -y install \
+ rw.tools-container-tools=5.2.0.0.71033 \
+ rw.tools-scripts=5.2.0.0.71033
-RUN /usr/rift/container_tools/mkcontainer --modes build --modes ext --repo OSM
+RUN /usr/rift/container_tools/mkcontainer --modes UI-dev --repo OSM --rw-version 5.2.0.0.71033
-RUN chmod 777 /usr/rift /usr/rift/usr/share
-
-RUN rm -rf /tmp/npm-cache
+RUN chmod 777 /usr/rift
params.GERRIT_PATCHSET_REVISION,
params.TEST_INSTALL,
params.ARTIFACTORY_SERVER)
-}
--- /dev/null
+#!/bin/bash
+
+#
+# Copyright 2016 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Post-install script for packaging
+
+/usr/rift/usr/share/rw.ui/skyquake/scripts/handle_plugin_node_modules
+++ /dev/null
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-env/
-build/
-develop-eggs/
-dist/
-deb_dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-*.egg-info/
-.installed.cfg
-*.egg
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*,cover
-.hypothesis/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
-
-# IPython Notebook
-.ipynb_checkpoints
-
-# pyenv
-.python-version
-
-# celery beat schedule file
-celerybeat-schedule
-
-# dotenv
-.env
-
-# virtualenv
-venv/
-ENV/
-
-# Spyder project settings
-.spyderproject
-
-# Rope project settings
-.ropeproject
+++ /dev/null
-package:
- @python setup.py --command-packages=stdeb.command bdist_deb > /dev/null 2>&1
+++ /dev/null
-# python-osmclient
-A python client for osm orchestration
-
-# Installation
-
-## Install dependencies
-```bash
-sudo apt-get install python-dev libcurl4-gnutls-dev python-pip libgnutls-dev python-prettytable
-sudo pip install pycurl
-```
-
-# Setup
-Set the OSM_HOSTNAME variable to the host of the osm server.
-
-Example
-```bash
-localhost$ export OSM_HOSTNAME=<hostname>:8008
-```
-
-# Examples
-
-## upload vnfd
-```bash
-localhost$ osm upload-package ubuntu_xenial_vnf.tar.gz
-{'transaction_id': 'ec12af77-1b91-4c84-b233-60f2c2c16d14'}
-localhost$ osm vnfd-list
-+--------------------+--------------------+
-| vnfd name | id |
-+--------------------+--------------------+
-| ubuntu_xenial_vnfd | ubuntu_xenial_vnfd |
-+--------------------+--------------------+
-```
-
-## upload nsd
-```bash
-localhost$ osm upload-package ubuntu_xenial_ns.tar.gz
-{'transaction_id': 'b560c9cb-43e1-49ef-a2da-af7aab24ce9d'}
-localhost$ osm nsd-list
-+-------------------+-------------------+
-| nsd name | id |
-+-------------------+-------------------+
-| ubuntu_xenial_nsd | ubuntu_xenial_nsd |
-+-------------------+-------------------+
-```
-## vim-list
-
-```bash
-localhost$ osm vim-list
-+-------------+-----------------+--------------------------------------+
-| ro-account | datacenter name | uuid |
-+-------------+-----------------+--------------------------------------+
-| osmopenmano | openstack-site | 2ea04690-0e4a-11e7-89bc-00163e59ff0c |
-+-------------+-----------------+--------------------------------------+
-```
-
-
-## instantiate ns
-```bash
-localhost$ osm ns-create ubuntu_xenial_nsd testns openstack-site
-{'success': ''}
-localhost$ osm ns-list
-+------------------+--------------------------------------+-------------------+--------------------+---------------+
-| ns instance name | id | catalog name | operational status | config status |
-+------------------+--------------------------------------+-------------------+--------------------+---------------+
-| testns | 6b0d2906-13d4-11e7-aa01-b8ac6f7d0c77 | ubuntu_xenial_nsd | running | configured |
-+------------------+--------------------------------------+-------------------+--------------------+---------------+
-```
-
-# Bash Completion
-python-osmclient uses [click](http://click.pocoo.org/5/). You can setup bash completion by putting this in your .bashrc:
-
- eval "$(_OSM_COMPLETE=source osm)"
-
+++ /dev/null
-from io import BytesIO
-import pycurl
-import json
-import pprint
-import uuid
-from prettytable import PrettyTable
-import time
-
-class OsmAPI():
- def __init__(self,host,upload_port=8443):
- if host is None:
- raise Exception('missing host specifier')
-
- self._user='admin'
- self._password='admin'
- self._host=host
- self._upload_port=upload_port
- self._url = 'https://{}/'.format(self._host)
- self._upload_url = 'https://{}:{}/'.format(self._host.split(':')[0],self._upload_port)
-
- def get_curl_cmd(self,url):
- curl_cmd = pycurl.Curl()
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.URL, self._url + url )
- curl_cmd.setopt(pycurl.SSL_VERIFYPEER,0)
- curl_cmd.setopt(pycurl.SSL_VERIFYHOST,0)
- curl_cmd.setopt(pycurl.USERPWD, '{}:{}'.format(self._user,self._password))
- curl_cmd.setopt(pycurl.HTTPHEADER, ['Accept: application/vnd.yand.data+json','Content-Type": "application/vnd.yang.data+json'])
- return curl_cmd
-
- def get_curl_upload_cmd(self,filename):
- curl_cmd = pycurl.Curl()
- curl_cmd.setopt(pycurl.HTTPPOST,[(('package',(pycurl.FORM_FILE,filename)))])
- curl_cmd.setopt(pycurl.URL, self._upload_url + 'composer/upload?api_server=https://localhost&upload_server=https://' + self._host.split(':')[0])
- curl_cmd.setopt(pycurl.SSL_VERIFYPEER,0)
- curl_cmd.setopt(pycurl.SSL_VERIFYHOST,0)
- curl_cmd.setopt(pycurl.USERPWD, '{}:{}'.format(self._user,self._password))
- return curl_cmd
-
- def get_ns_opdata(self,id):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/operational/ns-instance-opdata/nsr/{}?deep'.format(id))
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- if data.getvalue():
- return json.loads(data.getvalue().decode())
- return None
-
- def get_ns_catalog(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/running/nsd-catalog/nsd')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- if data.getvalue():
- resp = json.loads(data.getvalue().decode())
- return resp
- return {'nsd:nsd': []}
-
- def get_config_agents(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/config/config-agent')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- if data.getvalue():
- resp = json.loads(data.getvalue().decode())
- if 'rw-config-agent:config-agent' in resp:
- return resp['rw-config-agent:config-agent']['account']
- return list()
-
- def delete_config_agent(self,name):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/config/config-agent/account/'+name)
- curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE")
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def add_config_agent(self,name,account_type,server,user,secret):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/config/config-agent')
- curl_cmd.setopt(pycurl.POST,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
-
- postdata={}
- postdata['account'] = list()
-
- account={}
- account['name'] = name
- account['account-type'] = account_type
- account['juju'] = {}
- account['juju']['user'] = user
- account['juju']['secret'] = secret
- account['juju']['ip-address'] = server
- postdata['account'].append(account)
-
- jsondata=json.dumps(postdata)
- curl_cmd.setopt(pycurl.POSTFIELDS,jsondata)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def get_ns_instance_list(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/running/ns-instance-config')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- return resp['nsr:ns-instance-config']
-
- def get_vnf_catalog(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/running/vnfd-catalog/vnfd')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- if data.getvalue():
- resp = json.loads(data.getvalue().decode())
- return resp
- return {'vnfd:vnfd': []}
-
- def get_vcs_info(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/operational/vcs/info')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- if data.getvalue():
- resp = json.loads(data.getvalue().decode())
- return resp['rw-base:info']['components']['component_info']
- return list()
-
- def get_vnfr_catalog(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('v1/api/operational/vnfr-catalog/vnfr')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- if data.getvalue():
- resp = json.loads(data.getvalue().decode())
- return resp
- return None
-
- def get_vnf(self,vnf_name):
- vnfs=self.get_vnfr_catalog()
- for vnf in vnfs['vnfr:vnfr']:
- if vnf_name == vnf['name']:
- return vnf
- return None
-
- def get_vnf_monitoring(self,vnf_name):
- vnf=self.get_vnf(vnf_name)
- if vnf is not None:
- if 'monitoring-param' in vnf:
- return vnf['monitoring-param']
- return None
-
- def get_ns_monitoring(self,ns_name):
- ns=self.get_ns(ns_name)
- if ns is None:
- raise Exception('cannot find ns {}'.format(ns_name))
-
- vnfs=self.get_vnfr_catalog()
- if vnfs is None:
- return None
- mon_list={}
- for vnf in vnfs['vnfr:vnfr']:
- if ns['id'] == vnf['nsr-id-ref']:
- if 'monitoring-param' in vnf:
- mon_list[vnf['name']] = vnf['monitoring-param']
-
- return mon_list
-
- def list_key_pair(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('v1/api/config/key-pair?deep')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- if 'nsr:key-pair' in resp:
- return resp['nsr:key-pair']
- return list()
-
- def list_ns_catalog(self):
- resp = self.get_ns_catalog()
- table=PrettyTable(['nsd name','id'])
- for ns in resp['nsd:nsd']:
- table.add_row([ns['name'],ns['id']])
- table.align='l'
- print(table)
-
- def list_ns_instance(self):
- resp = self.get_ns_instance_list()
- table=PrettyTable(['ns instance name','id','catalog name','operational status','config status'])
- if 'nsr' in resp:
- for ns in resp['nsr']:
- nsopdata=self.get_ns_opdata(ns['id'])
- nsr=nsopdata['nsr:nsr']
- table.add_row([nsr['name-ref'],nsr['ns-instance-config-ref'],nsr['nsd-name-ref'],nsr['operational-status'],nsr['config-status']])
- table.align='l'
- print(table)
-
- def get_nsd(self,name):
- resp = self.get_ns_catalog()
- for ns in resp['nsd:nsd']:
- if name == ns['name']:
- return ns
- return None
-
- def get_vnfd(self,name):
- resp = self.get_vnf_catalog()
- for vnf in resp['vnfd:vnfd']:
- if name == vnf['name']:
- return vnf
- return None
-
- def get_ns(self,name):
- resp=self.get_ns_instance_list()
- for ns in resp['nsr']:
- if name == ns['name']:
- return ns
- return None
-
- def instantiate_ns(self,nsd_name,nsr_name,account,vim_network_prefix=None,ssh_keys=None,description='default description',admin_status='ENABLED'):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/config/ns-instance-config/nsr')
- curl_cmd.setopt(pycurl.POST,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
-
- postdata={}
- postdata['nsr'] = list()
- nsr={}
- nsr['id']=str(uuid.uuid1())
-
- nsd=self.get_nsd(nsd_name)
- if nsd is None:
- raise Exception('cannot find nsd {}'.format(nsd_name))
-
- datacenter=self.get_datacenter(account)
- if datacenter is None:
- raise Exception('cannot find datacenter account {}'.format(account))
-
- nsr['nsd']=nsd
- nsr['name']=nsr_name
- nsr['short-name']=nsr_name
- nsr['description']=description
- nsr['admin-status']=admin_status
- nsr['om-datacenter']=datacenter['uuid']
-
- if ssh_keys is not None:
- # ssh_keys is comma separate list
- ssh_keys_format=[]
- for key in ssh_keys.split(','):
- ssh_keys_format.append({'key-pair-ref':key})
-
- nsr['ssh-authorized-key']=ssh_keys_format
-
- if vim_network_prefix is not None:
- for index,vld in enumerate(nsr['nsd']['vld']):
- network_name = vld['name']
- nsr['nsd']['vld'][index]['vim-network-name'] = '{}-{}'.format(vim_network_prefix,network_name)
-
- postdata['nsr'].append(nsr)
- jsondata=json.dumps(postdata)
- curl_cmd.setopt(pycurl.POSTFIELDS,jsondata)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def delete_nsd(self,nsd_name):
- nsd=self.get_nsd(nsd_name)
- if nsd is None:
- raise Exception('cannot find nsd {}'.format(nsd_name))
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/running/nsd-catalog/nsd/'+nsd['id'])
- curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE")
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def delete_vnfd(self,vnfd_name):
- vnfd=self.get_vnfd(vnfd_name)
- if vnfd is None:
- raise Exception('cannot find vnfd {}'.format(vnfd_name))
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/running/vnfd-catalog/vnfd/'+vnfd['id'])
- curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE")
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def terminate_ns(self,ns_name):
- ns=self.get_ns(ns_name)
- if ns is None:
- raise Exception('cannot find ns {}'.format(ns_name))
-
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/config/ns-instance-config/nsr/'+ns['id'])
- curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE")
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def upload_package(self,filename):
- data = BytesIO()
- curl_cmd=self.get_curl_upload_cmd(filename)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def add_vim_account(self,name,user_name,secret,auth_url,tenant,mgmt_network,float_ip_pool,account_type='openstack'):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('api/config/cloud')
- curl_cmd.setopt(pycurl.POST,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- vim_account={}
- vim_account['account']={}
-
- vim_account['account']['name'] = name
- vim_account['account']['account-type'] = account_type
- vim_account['account'][account_type] = {}
- vim_account['account'][account_type]['key'] = user_name
- vim_account['account'][account_type]['secret'] = secret
- vim_account['account'][account_type]['auth_url'] = auth_url
- vim_account['account'][account_type]['tenant'] = tenant
- vim_account['account'][account_type]['mgmt-network'] = mgmt_network
- vim_account['account'][account_type]['floating-ip-pool'] = float_ip_pool
-
- jsondata=json.dumps(vim_account)
- curl_cmd.setopt(pycurl.POSTFIELDS,jsondata)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- pprint.pprint(resp)
-
- def list_vim_accounts(self):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('v1/api/operational/datacenters')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- datacenters=resp['rw-launchpad:datacenters']
- if 'ro-accounts' in datacenters:
- return datacenters['ro-accounts']
- return list()
-
- def get_datacenter(self,name):
- data = BytesIO()
- curl_cmd=self.get_curl_cmd('v1/api/operational/datacenters')
- curl_cmd.setopt(pycurl.HTTPGET,1)
- curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
- curl_cmd.perform()
- curl_cmd.close()
- resp = json.loads(data.getvalue().decode())
- datacenters=resp['rw-launchpad:datacenters']
- if 'ro-accounts' in datacenters:
- for roaccount in datacenters['ro-accounts']:
- if not 'datacenters' in roaccount:
- continue
- for datacenter in roaccount['datacenters']:
- if datacenter['name'] == name:
- return datacenter
- return None
-
- def show_ns(self,ns_name):
- resp = self.get_ns_instance_list()
- table=PrettyTable(['attribute','value'])
-
- if 'nsr' in resp:
- for ns in resp['nsr']:
- if ns_name == ns['name']:
- # dump ns config
- for k,v in ns.items():
- table.add_row([k,json.dumps(v,indent=2)])
-
- nsopdata=self.get_ns_opdata(ns['id'])
- nsr_optdata=nsopdata['nsr:nsr']
- for k,v in nsr_optdata.items():
- table.add_row([k,json.dumps(v,indent=2)])
- table.align='l'
- print(table)
-
- def show_ns_scaling(self,ns_name):
- resp = self.get_ns_instance_list()
-
- table=PrettyTable(['instance-id','operational status','create-time','vnfr ids'])
-
- if 'nsr' in resp:
- for ns in resp['nsr']:
- if ns_name == ns['name']:
- nsopdata=self.get_ns_opdata(ns['id'])
- scaling_records=nsopdata['nsr:nsr']['scaling-group-record']
- for record in scaling_records:
- if 'instance' in record:
- instances=record['instance']
- for inst in instances:
- table.add_row([inst['instance-id'],inst['op-status'],time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(inst['create-time'])),inst['vnfrs']])
- table.align='l'
- print(table)
-
- def list_vnfr(self):
- return self.get_vnfr_catalog()
-
- def list_vnf_catalog(self):
- resp = self.get_vnf_catalog()
- table=PrettyTable(['vnfd name','id'])
- for ns in resp['vnfd:vnfd']:
- table.add_row([ns['name'],ns['id']])
- table.align='l'
- print(table)
+++ /dev/null
-import click
-from osmclient.common import OsmAPI
-from prettytable import PrettyTable
-import pprint
-import textwrap
-
-@click.group()
-@click.option('--hostname',default=None,envvar='OSM_HOSTNAME',help='hostname of server. Also can set OSM_HOSTNAME in environment')
-@click.pass_context
-def cli(ctx,hostname):
- if hostname is None:
- print("either hostname option or OSM_HOSTNAME environment variable needs to be specified")
- exit(1)
- ctx.obj=OsmAPI.OsmAPI(hostname)
-
-@cli.command(name='ns-list')
-@click.pass_context
-def ns_list(ctx):
- ctx.obj.list_ns_instance()
-
-@cli.command(name='nsd-list')
-@click.pass_context
-def nsd_list(ctx):
- ctx.obj.list_ns_catalog()
-
-@cli.command(name='vnfd-list')
-@click.pass_context
-def vnfd_list(ctx):
- ctx.obj.list_vnf_catalog()
-
-@cli.command(name='vnf-list')
-@click.pass_context
-def vnf_list(ctx):
- resp=ctx.obj.list_vnfr()
- table=PrettyTable(['vnf name','id','operational status','config Status','mgmt interface','nsr id'])
- if resp is not None:
- for vnfr in resp['vnfr:vnfr']:
- if not 'mgmt-interface' in vnfr:
- vnfr['mgmt-interface'] = {}
- vnfr['mgmt-interface']['ip-address'] = None
- table.add_row([vnfr['name'],vnfr['id'],vnfr['operational-status'],vnfr['config-status'],vnfr['mgmt-interface']['ip-address'],vnfr['nsr-id-ref']])
- table.align='l'
- print(table)
-
-@cli.command(name='vnf-monitoring-show')
-@click.argument('vnf_name')
-@click.pass_context
-def vnf_monitoring_show(ctx,vnf_name):
- resp=ctx.obj.get_vnf_monitoring(vnf_name)
- table=PrettyTable(['vnf name','monitoring name','value','units'])
- if resp is not None:
- for monitor in resp:
- table.add_row([vnf_name,monitor['name'],monitor['value-integer'],monitor['units']])
- table.align='l'
- print(table)
-
-@cli.command(name='ns-monitoring-show')
-@click.argument('ns_name')
-@click.pass_context
-def ns_monitoring_show(ctx,ns_name):
- resp=ctx.obj.get_ns_monitoring(ns_name)
- table=PrettyTable(['vnf name','monitoring name','value','units'])
- if resp is not None:
- for key,val in resp.items():
- for monitor in val:
- table.add_row([key,monitor['name'],monitor['value-integer'],monitor['units']])
- table.align='l'
- print(table)
-
-@cli.command(name='ns-create')
-@click.argument('nsd_name')
-@click.argument('ns_name')
-@click.argument('vim_account')
-@click.option('--admin_status',default='ENABLED',help='administration status')
-@click.option('--ssh_keys',default=None,help='comma separated list of keys to inject to vnfs')
-@click.option('--vim_network_prefix',default=None,help='vim network name prefix')
-@click.pass_context
-def ns_create(ctx,nsd_name,ns_name,vim_account,admin_status,ssh_keys,vim_network_prefix):
- ctx.obj.instantiate_ns(nsd_name,ns_name,vim_network_prefix=vim_network_prefix,ssh_keys=ssh_keys,account=vim_account)
-
-@cli.command(name='ns-delete')
-@click.argument('ns_name')
-@click.pass_context
-def ns_delete(ctx,ns_name):
- ctx.obj.terminate_ns(ns_name)
-
-'''
-@cli.command(name='keypair-list')
-@click.pass_context
-def keypair_list(ctx):
- resp=ctx.obj.list_key_pair()
- table=PrettyTable(['key Name','key'])
- for kp in resp:
- table.add_row([kp['name'],kp['key']])
- table.align='l'
- print(table)
-'''
-
-@cli.command(name='upload-package')
-@click.argument('filename')
-@click.pass_context
-def upload_package(ctx,filename):
- ctx.obj.upload_package(filename)
-
-@cli.command(name='ns-show')
-@click.argument('ns_name')
-@click.pass_context
-def ns_show(ctx,ns_name):
- ctx.obj.show_ns(ns_name)
-
-@cli.command(name='ns-scaling-show')
-@click.argument('ns_name')
-@click.pass_context
-def show_ns_scaling(ctx,ns_name):
- ctx.obj.show_ns_scaling(ns_name)
-
-@cli.command(name='nsd-delete')
-@click.argument('nsd_name')
-@click.pass_context
-def nsd_delete(ctx,nsd_name):
- ctx.obj.delete_nsd(nsd_name)
-
-@cli.command(name='vnfd-delete')
-@click.argument('vnfd_name')
-@click.pass_context
-def nsd_delete(ctx,vnfd_name):
- ctx.obj.delete_vnfd(vnfd_name)
-
-@cli.command(name='config-agent-list')
-@click.pass_context
-def config_agent_list(ctx):
- table=PrettyTable(['name','account-type','details'])
- for account in ctx.obj.get_config_agents():
- table.add_row([account['name'],account['account-type'],account['juju']])
- table.align='l'
- print(table)
-
-@cli.command(name='config-agent-delete')
-@click.argument('name')
-@click.pass_context
-def config_agent_delete(ctx,name):
- ctx.obj.delete_config_agent(name)
-
-@cli.command(name='config-agent-add')
-@click.argument('name')
-@click.argument('account_type')
-@click.argument('server')
-@click.argument('user')
-@click.argument('secret')
-@click.pass_context
-def config_agent_add(ctx,name,account_type,server,user,secret):
- ctx.obj.add_config_agent(name,account_type,server,user,secret)
-
-'''
-@cli.command(name='vim-create')
-@click.argument('name')
-@click.argument('user')
-@click.argument('password')
-@click.argument('auth_url')
-@click.argument('tenant')
-@click.argument('mgmt_network')
-@click.argument('floating_ip_pool')
-@click.option('--account_type',default='openstack')
-@click.pass_context
-def vim_create(ctx,name,user,password,auth_url,tenant,mgmt_network,floating_ip_pool,account_type):
- ctx.obj.add_vim_account(name,user,password,auth_url,tenant,mgmt_network,floating_ip_pool,account_type)
-'''
-
-@cli.command(name='vim-list')
-@click.pass_context
-def vim_list(ctx):
- resp=ctx.obj.list_vim_accounts()
- table=PrettyTable(['ro-account','datacenter name','uuid'])
- for roaccount in resp:
- for datacenter in roaccount['datacenters']:
- table.add_row([roaccount['name'],datacenter['name'],datacenter['uuid']])
- table.align='l'
- print(table)
-
-@cli.command(name='vcs-list')
-@click.pass_context
-def vcs_list(ctx):
- resp=ctx.obj.get_vcs_info()
- table=PrettyTable(['component name','state'])
- for component in resp:
- table.add_row([component['component_name'],component['state']])
- table.align='l'
- print(table)
-
-if __name__ == '__main__':
- cli()
+++ /dev/null
-from setuptools import setup,find_packages
-
-setup(
- name='osmclient',
- version='0.1',
- author='Mike Marchetti',
- author_email='mmarchetti@sandvine.com',
- packages=find_packages(),
- include_package_data=True,
- install_requires=[
- 'Click','prettytable'
- ],
- entry_points='''
- [console_scripts]
- osm=osmclient.scripts.osm:cli
- ''',
-)
+++ /dev/null
-[DEFAULT]
-Depends: python-setuptools, python-pycurl, python-click, python-prettytable
// require('../tests/stories/sshKeyCard');
// require('../tests/stories/button');
// require('../tests/stories/sq-input-slider');
- require('../tests/stories/catalogCard');
+ // require('../tests/stories/catalogCard');
+ require('../tests/stories/FileManager');
+ require('../tests/stories/inputs');
// require as many stories as you need.
}
configure(loadStories, module);
+
+
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * Auth util for use across the api_server.
+ * @module framework/core/api_utils/auth
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var jsonLoader = require('require-json');
+var passport = require('passport');
+var OpenIdConnectStrategy = require('passport-openidconnect').Strategy;
+var BearerStrategy = require('passport-http-bearer').Strategy;
+var OAuth2Strategy = require('passport-oauth2');
+var OAuth2RefreshTokenStrategy = require('passport-oauth2-middleware').Strategy;
+var openidConnectConfig = require('./openidconnect_config.json');
+var _ = require('lodash');
+var constants = require('./constants');
+var utils = require('./utils');
+var request = utils.request;
+var rp = require('request-promise');
+var nodeutil = require('util');
+
+
+var Authorization = function(openidConfig) {
+
+ var self = this;
+
+ self.passport = passport;
+
+ self.openidConnectConfig = openidConnectConfig;
+
+ var refreshStrategy = new OAuth2RefreshTokenStrategy({
+ refreshWindow: constants.REFRESH_WINDOW, // Time in seconds to perform a token refresh before it expires
+ userProperty: 'user', // Active user property name to store OAuth tokens
+ authenticationURL: '/login', // URL to redirect unauthorized users to
+ callbackParameter: 'callback' //URL query parameter name to pass a return URL
+ });
+
+ self.passport.use('main', refreshStrategy);
+
+ var openidConfigPrefix = openidConfig.idpServerProtocol + '://' + openidConfig.idpServerAddress + ':' + openidConfig.idpServerPortNumber;
+
+ self.openidConnectConfig.authorizationURL = openidConfigPrefix + self.openidConnectConfig.authorizationURL;
+ self.openidConnectConfig.tokenURL = openidConfigPrefix + self.openidConnectConfig.tokenURL;
+ self.openidConnectConfig.callbackURL = openidConfig.callbackServerProtocol + '://' + openidConfig.callbackAddress + ':' + openidConfig.callbackPortNumber + self.openidConnectConfig.callbackURL;
+
+ var userInfoURL = openidConfigPrefix + self.openidConnectConfig.userInfoURL;
+
+ function SkyquakeOAuth2Strategy(options, verify) {
+ OAuth2Strategy.call(this, options, verify);
+ }
+ nodeutil.inherits(SkyquakeOAuth2Strategy, OAuth2Strategy);
+
+ SkyquakeOAuth2Strategy.prototype.userProfile = function(access_token, done) {
+
+ var requestHeaders = {
+ 'Authorization': 'Bearer ' + access_token
+ };
+
+ request({
+ url: userInfoURL,
+ type: 'GET',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: constants.REJECT_UNAUTHORIZED
+ }, function(err, response, body) {
+ if (err) {
+ console.log('Error obtaining userinfo: ', err);
+ return done(null, {
+ username: '',
+ subject: ''
+ });
+ } else {
+ if (response.statusCode == constants.HTTP_RESPONSE_CODES.SUCCESS.OK) {
+ try {
+ var data = JSON.parse(response.body);
+ var username = data['preferred_username'];
+ var subject = data['sub'];
+ var domain = data['user_domain'] || 'system';
+ return done(null, {
+ username: username,
+ subject: subject,
+ domain: domain
+ })
+ } catch (ex) {
+ console.log('Error parsing userinfo data');
+ return done(null, {
+ username: '',
+ subject: ''
+ });
+ }
+ }
+ }
+ })
+ };
+
+ var oauthStrategy = new SkyquakeOAuth2Strategy(self.openidConnectConfig,
+ refreshStrategy.getOAuth2StrategyCallback());
+
+ self.passport.use('oauth2', oauthStrategy);
+ refreshStrategy.useOAuth2Strategy(oauthStrategy);
+
+ self.passport.serializeUser(function(user, done) {
+ done(null, user);
+ });
+
+ self.passport.deserializeUser(function(obj, done) {
+ done(null, obj);
+ });
+
+};
+
+Authorization.prototype.configure = function(config) {
+ this.config = config;
+ // Initialize Passport and restore authentication state, if any, from the
+ // session.
+ if (this.config.app) {
+ this.config.app.use(this.passport.initialize());
+ this.config.app.use(this.passport.session());
+ } else {
+ console.log('FATAL error. Bad config passed into authorization module');
+ }
+};
+
+Authorization.prototype.invalidate_token = function(token) {
+
+};
+
+module.exports = Authorization;
constants.SOCKET_POOL_LENGTH = 20;
constants.SERVER_PORT = process.env.SERVER_PORT || 8000;
constants.SECURE_SERVER_PORT = process.env.SECURE_SERVER_PORT || 8443;
+constants.REJECT_UNAUTHORIZED = false;
-constants.BASE_PACKAGE_UPLOAD_DESTINATION = 'upload/packages/';
+constants.BASE_PACKAGE_UPLOAD_DESTINATION = 'upload';
constants.PACKAGE_MANAGER_SERVER_PORT = 4567;
constants.PACKAGE_FILE_DELETE_DELAY_MILLISECONDS = 3 * 1000 * 60; //5 minutes
constants.PACKAGE_FILE_ONBOARD_TRANSACTION_STATUS_CHECK_DELAY_MILLISECONDS = 2 * 1000; //2 seconds
+constants.REFRESH_WINDOW = 10; //Time in seconds to perform a token refresh before it expires
+constants.LAUNCHPAD_ADDRESS = 'localhost';
+constants.LAUNCHPAD_PORT = 8008;
+constants.IDP_SERVER_PROTOCOL = 'https';
+constants.IDP_PORT_NUMBER = 8009;
+constants.CALLBACK_SERVER_PROTOCOL = 'https';
+constants.CALLBACK_PORT_NUMBER = 8443;
+constants.CALLBACK_ADDRESS = 'localhost';
+constants.END_SESSION_PATH = 'end_session';
module.exports = constants;
\ No newline at end of file
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * CSRF util for use across the api_server.
+ * @module framework/core/api_utils/csrf
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var constants = require('./constants.js');
+var utils = require('./utils.js');
+
+var target = null;
+
+function configure(config) {
+ target = config.target;
+}
+
+function csrfCheck(req, res, next) {
+ var host = null;
+
+ if (req.headers.origin != 'null') {
+ host = utils.getHostNameFromURL(req.headers.origin);
+ } else if (req.headers.referer) {
+ host = utils.getHostNameFromURL(req.headers.referer);
+ } else {
+ var msg = 'Request did not contain an origin or referer header. Request terminated.';
+ var error = {};
+ error.statusCode = constants.HTTP_RESPONSE_CODES.ERROR.METHOD_NOT_ALLOWED;
+ error.errorMessage = {
+ error: msg
+ }
+ return utils.sendErrorResponse(error, res);
+ }
+
+ if (!host || host != target) {
+ var msg = 'Request did not originate from authorized source (Potential CSRF attempt). Request terminated.';
+ var error = {};
+ error.statusCode = constants.HTTP_RESPONSE_CODES.ERROR.METHOD_NOT_ALLOWED;
+ error.errorMessage = {
+ error: msg
+ }
+ return utils.sendErrorResponse(error, res);
+ } else {
+ return next();
+ }
+}
+
+module.exports = {
+ configure: configure,
+ csrfCheck: csrfCheck
+};
\ No newline at end of file
--- /dev/null
+{
+ "scope": "openid",
+ "clientID": "cncudWkub3BlbmlkY2xpZW50",
+ "clientSecret": "riftiorocks",
+ "authorizationURL": "/authorization",
+ "tokenURL": "/token",
+ "userInfoURL": "/userinfo",
+ "callbackURL": "/callback"
+}
\ No newline at end of file
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
var sockjs = require('sockjs');
var websocket_multiplex = require('websocket-multiplex');
var utils = require('./utils.js');
+var configurationAPI = require('../modules/api/configuration.js');
var Subscriptions = function() {
if (Type == PollingSocket) {
Socket = new Type(url, req, 1000, req.body);
} else {
- Socket = new Type(url);
+ Socket = new Type(url, ['Bearer', req.session.passport.user.user['access_token']]);
}
console.log('Socket assigned for url', url);
}
self.isClosed = false;
var requestHeaders = {};
_.extend(requestHeaders, {
- 'Authorization': req.get('Authorization')
+ Cookie: req.get('Cookie')
});
var pollServer = function() {
Request({
- url: url,
+ url: utils.projectContextUrl(req, url),
method: config.method || 'GET',
headers: requestHeaders,
json: config.payload,
console.log('Error polling: ' + url);
} else {
if (!self.isClosed) {
- self.poll = setTimeout(pollServer, 1000 || interval);
+ if(process.env.DISABLE_POLLING != "TRUE") {
+ self.poll = setTimeout(pollServer, 1000 || interval);
+ } else {
+ console.log('Polling is disabled. Finishing request.')
+ }
var data = response.body;
if (self.onmessage) {
self.onmessage(data);
return api_server + ':' + CONFD_PORT;
};
+var projectContextUrl = function(req, url) {
+ //NOTE: We need to go into the sessionStore because express-session
+ // does not reliably update the session.
+ // See https://github.com/expressjs/session/issues/450
+ var projectId = (req.session &&
+ req.sessionStore &&
+ req.sessionStore.sessions &&
+ req.sessionStore.sessions[req.session.id] &&
+ JSON.parse(req.sessionStore.sessions[req.session.id])['projectId']) ||
+ (null);
+ if (projectId) {
+ projectId = encodeURIComponent(projectId);
+ return url.replace(/(\/api\/operational\/|\/api\/config\/)(.*)/, '$1project/' + projectId + '/$2');
+ }
+ return url;
+}
+
+var addProjectContextToRPCPayload = function(req, url, inputPayload) {
+ //NOTE: We need to go into the sessionStore because express-session
+ // does not reliably update the session.
+ // See https://github.com/expressjs/session/issues/450
+ var projectId = (req.session &&
+ req.sessionStore &&
+ req.sessionStore.sessions &&
+ req.sessionStore.sessions[req.session.id] &&
+ JSON.parse(req.sessionStore.sessions[req.session.id])['projectId']) ||
+ (null);
+ if (projectId) {
+ if (url.indexOf('/api/operations/')) {
+ inputPayload['project-name'] = projectId;
+ }
+ }
+ return inputPayload;
+}
+
var validateResponse = function(callerName, error, response, body, resolve, reject) {
var res = {};
};
reject(res);
return false;
- } else if (response.statusCode >= 400) {
+ } else if (response.statusCode >= CONSTANTS.HTTP_RESPONSE_CODES.ERROR.BAD_REQUEST) {
console.log('Problem with "', callerName, '": ', response.statusCode, ':', body);
res.statusCode = response.statusCode;
// auth specific
- if (response.statusCode == 401) {
+ if (response.statusCode == CONSTANTS.HTTP_RESPONSE_CODES.ERROR.UNAUTHORIZED) {
res.errorMessage = {
error: 'Authentication needed' + body
};
reject(res);
return false;
- } else if (response.statusCode == 204) {
+ } else if (response.statusCode == CONSTANTS.HTTP_RESPONSE_CODES.SUCCESS.NO_CONTENT) {
resolve({
statusCode: response.statusCode,
data: {}
var checkAuthorizationHeader = function(req) {
return new Promise(function(resolve, reject) {
- if (req.get('Authorization') == null) {
+ if (req.session && req.session.authorization == null) {
reject();
} else {
resolve();
reject(res);
fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Error: ' + error);
return false;
- } else if (response.statusCode >= 400) {
+ } else if (response.statusCode >= CONSTANTS.HTTP_RESPONSE_CODES.ERROR.BAD_REQUEST) {
console.log('Problem with "', callerName, '": ', response.statusCode, ':', body);
res.statusCode = response.statusCode;
// auth specific
- if (response.statusCode == 401) {
+ if (response.statusCode == CONSTANTS.HTTP_RESPONSE_CODES.ERROR.UNAUTHORIZED) {
res.errorMessage = {
error: 'Authentication needed' + body
};
reject(res);
fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Error Body: ' + body);
return false;
- } else if (response.statusCode == 204) {
+ } else if (response.statusCode == CONSTANTS.HTTP_RESPONSE_CODES.SUCCESS.NO_CONTENT) {
resolve();
fs.appendFileSync(logFile, 'Request API: ' + response.request.uri.href + ' ; ' + 'Response Body: ' + body);
return false;
* @param {Function} res - a handle to the express response function
*/
var sendErrorResponse = function(error, res) {
+ if (!error.statusCode) {
+ console.error('Status Code has not been set in error object: ', error);
+ }
res.status(error.statusCode);
res.send(error);
}
}
new Promise(function(resolve, reject) {
request({
- uri: uri,
+ uri: projectContextUrl(req, uri),
method: 'GET',
headers: _.extend({}, CONSTANTS.HTTP_HEADERS.accept[type], {
- 'Authorization': req.get('Authorization'),
+ 'Authorization': req.session && req.session.authorization,
forever: CONSTANTS.FOREVER_ON,
rejectUnauthorized: false,
})
}
}
+var buildRedirectURL = function(req, globalConfiguration, plugin, extra) {
+ var api_server = req.query['api_server'] || (req.protocol + '://' + globalConfiguration.get().api_server);
+ var download_server = req.query['dev_download_server'] || globalConfiguration.get().dev_download_server;
+ var url = '/';
+ url += plugin;
+ url += '/?api_server=' + api_server;
+ url += download_server ? '&dev_download_server=' + download_server : '';
+ url += extra || '';
+ return url;
+}
+
+var getHostNameFromURL = function(url) {
+ var match = url.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([^?#]*)(\?[^#]*|)(#.*|)$/);
+ return match && match[3];
+}
+
+var dataToJsonSansPropNameNamespace = function(s) {
+ var a = JSON.parse(s);
+ var b = JSON.stringify(a);
+ var c = b.replace(/{"[-\w]+:/g, '{"');
+ var d = c.replace(/,"[-\w]+:/g, ',"');
+ var j = JSON.parse(d);
+ return j;
+}
+
module.exports = {
/**
* Ensure confd port is on api_server variable.
passThroughConstructor: passThroughConstructor,
- getPortForProtocol: getPortForProtocol
+ getPortForProtocol: getPortForProtocol,
+
+ projectContextUrl: projectContextUrl,
+
+ addProjectContextToRPCPayload: addProjectContextToRPCPayload,
+
+ buildRedirectURL: buildRedirectURL,
+
+ getHostNameFromURL: getHostNameFromURL,
+
+ dataToJsonSansPropNameNamespace: dataToJsonSansPropNameNamespace
};
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// DescriptorModelMeta API (NSD + VNFD)
+
+
+var Schema = {};
+var request = require('request');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var _ = require('lodash');
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var utils = require('../../api_utils/utils');
+var sessionAPI = require('./sessions.js');
+var configuration = require('./configuration');
+
+var router = require('express').Router();
+
+router.use(bodyParser.json());
+router.use(cors());
+router.use(bodyParser.urlencoded({
+ extended: true
+}));
+
+router.get('/app-config', cors(), function (req, res) {
+ getConfig(req).then(function (response) {
+ utils.sendSuccessResponse(response, res);
+ }, function (error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+var inactivityTimeout = process.env.UI_TIMEOUT_SECS || 600000;
+
+var versionPromise = null;
+
+var init = function () {
+ versionPromise = new Promise(
+ function (resolve, reject) {
+ sessionAPI.sessionPromise.then(
+ function (session) {
+ request({
+ url: configuration.getBackendURL() + '/api/operational/version',
+ type: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false
+ },
+ function (error, response, body) {
+ var data;
+ if (utils.validateResponse('schema/version.get', error, response, body, resolve, reject)) {
+ try {
+ data = JSON.parse(response.body)['rw-base:version'];
+ resolve(data.version);
+ } catch (e) {
+ return reject({});
+ }
+ } else {
+ console.log(error);
+ }
+ });
+ });
+ });
+}
+
+var getConfig = function (req) {
+ var api_server = req.query['api_server'];
+
+ var requests = [versionPromise];
+
+ return new Promise(function (resolve, reject) {
+ Promise.all(requests).then(
+ function (results) {
+ var data = {
+ version: results[0],
+ 'api-server': configuration.getBackendURL,
+ 'inactivity-timeout': process.env.UI_TIMEOUT_SECS || 600000
+ }
+ resolve({
+ data: data,
+ statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+ });
+ }).catch(
+ function (error) {
+ var response = {};
+ console.log('Problem with config.get', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to get config' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+module.exports = {
+ getRouter: function () {
+ return router;
+ },
+ init: init
+};
\ No newline at end of file
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
var _ = require('lodash');
var GLOBAL_CONFIGURATION = {
api_server: 'localhost',
- ssl_enabled: true
+ ssl_enabled: true,
+ api_server_port_number: constants.SECURE_SERVER_PORT,
+ idp_server_address: constants.LAUNCHPAD_ADDRESS,
+ idp_server_protocol: constants.IDP_SERVER_PROTOCOL,
+ idp_server_port_number: constants.IDP_PORT_NUMBER
};
/**
return GLOBAL_CONFIGURATION;
};
+var backendURL = null;
+configurationAPI.getBackendURL = function () {
+ if (!backendURL) {
+ backendURL = GLOBAL_CONFIGURATION.api_server_protocol + '://' + GLOBAL_CONFIGURATION.api_server + ':' + GLOBAL_CONFIGURATION.api_server_port_number;
+ }
+ return backendURL;
+}
+
+configurationAPI.getBackendAPI = function () {
+ return configurationAPI.getBackendURL() + '/v2/api';
+}
+
+
+
module.exports = configurationAPI;
uri: utils.confdPort(api_server) + '/api/schema/nsd-catalog/nsd',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
- 'Authorization': req.get('Authorization')
+ 'Authorization': req.session && req.session.authorization
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
uri: utils.confdPort(api_server) + '/api/schema/vnfd-catalog/vnfd',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
- 'Authorization': req.get('Authorization')
+ 'Authorization': req.session && req.session.authorization
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// DescriptorModelMeta API (NSD + VNFD)
+
+
+var Schema = {};
+var rp = require('request-promise');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var _ = require('lodash');
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var utils = require('../../api_utils/utils');
+var configuration = require('./configuration');
+
+var router = require('express').Router();
+
+
+router.use(bodyParser.json());
+router.use(cors());
+router.use(bodyParser.urlencoded({
+ extended: true
+}));
+
+router.get('/model', cors(), function (req, res) {
+ get(req).then(function (response) {
+ utils.sendSuccessResponse(response, res);
+ }, function (error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+router.patch('/model', cors(), function (req, res) {
+ update(req).then(function (response) {
+ utils.sendSuccessResponse(response, res);
+ }, function (error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+router.put('/model', cors(), function (req, res) {
+ add(req).then(function (response) {
+ utils.sendSuccessResponse(response, res);
+ }, function (error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+router.delete('/model', cors(), function (req, res) {
+ remove(req).then(function (response) {
+ utils.sendSuccessResponse(response, res);
+ }, function (error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+module.exports = {
+ getRouter: function () {
+ return router;
+ },
+ init: function () {}
+};
+
+get = function (req) {
+ var backend = configuration.getBackendAPI();
+ var modelPath = req.query['path'];
+ var requestHeaders = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+ 'Authorization': req.session && req.session.authorization
+ })
+ return new Promise(function (resolve, reject) {
+ Promise.all([
+ rp({
+ uri: backend + '/config' + modelPath,
+ method: 'GET',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ // }),
+ // rp({
+ // uri: utils.projectContextUrl(req, backend + '/api/operational' + modelPath),
+ // method: 'GET',
+ // headers: requestHeaders,
+ // forever: constants.FOREVER_ON,
+ // rejectUnauthorized: false,
+ // resolveWithFullResponse: true
+ })
+ ]).then(function (results) {
+ var response = {
+ statusCode: results[0].statusCode || 200,
+ data: [null]
+ }
+ if (results[0].body && !results[0].error) {
+ var result = JSON.parse(results[0].body);
+ if (result.collection) {
+ result = result.collection[Object.keys(result.collection)[0]];
+ if (!result.length) {
+ result = null;
+ } else if (result.length === 1) {
+ result = result[0];
+ }
+ }
+ response.data = result;
+ }
+ resolve(response);
+
+ }).catch(function (error) {
+ var res = {};
+ console.log('Problem with model get', error);
+ res.statusCode = error.statusCode || 500;
+ res.errorMessage = {
+ error: 'Failed to get model: ' + error
+ };
+ reject(res);
+ });
+ });
+};
+
+add = function (req) {
+ var backend = configuration.getBackendAPI();
+ var modelPath = req.query['path'];
+ var targetProperty = modelPath.split('/').pop();
+ var newElement = {};
+ var data = {};
+ console.log(req.body);
+ _.forIn(req.body, function (value, key) {
+ if (_.isObject(value)) {
+ if (value.type === 'leaf_empty') {
+ if (value.data) {
+ data[key] = ' ';
+ }
+ } else if (value.type === 'leaf_list') {
+ data[key] = value.data.add;
+ }
+ } else {
+ data[key] = value;
+ }
+ });
+ newElement[targetProperty] = [data];
+ console.log(newElement);
+ var target = backend + '/config' + modelPath;
+ var method = 'POST'
+ var requestHeaders = _.extend({},
+ constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ });
+ return new Promise(function (resolve, reject) {
+ rp({
+ uri: target,
+ method: method,
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ json: newElement,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ }).then(function (results) {
+ var response = {};
+ response.data = {
+ path: modelPath,
+ data: data
+ };
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK;
+ console.log(response);
+ resolve(response);
+ }).catch(function (result) {
+ var response = {};
+ var error = {};
+ if (result.error['rpc-reply']) {
+ error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
+ error.message = result.error['rpc-reply']['rpc-error']['error-message'];
+ error.rpcError = result.error['rpc-reply']['rpc-error']
+ } else {
+ error.type = 'api-error';
+ error.message = 'invalid api call';
+ }
+ console.log('Problem with model update', error);
+ response.statusCode = error.statusCode || 500;
+ response.error = error;
+ reject(response);
+ });
+ });
+};
+
+update = function (req) {
+ var backend = configuration.getBackendAPI();
+ var modelPath = req.query['path'];
+ var requestHeaders = _.extend({},
+ constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ });
+ var base = backend + '/config' + modelPath + '/';
+
+ function getUpdatePromise(name, value) {
+ var data = {};
+ data[name] = value;
+ return new Promise(function (resolve, reject) {
+ rp({
+ uri: base + name,
+ method: value ? 'PATCH' : 'DELETE',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ json: data,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ }).then(function (result) {
+ resolve({
+ element: name,
+ success: true,
+ value: value
+ });
+ }).catch(function (result) {
+ var error = {};
+ if (result.error['rpc-reply']) {
+ error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
+ error.message = result.error['rpc-reply']['rpc-error']['error-message'];
+ error.rpcError = result.error['rpc-reply']['rpc-error']
+ } else {
+ error.type = 'api-error';
+ error.message = 'invalid api call';
+ }
+ resolve({
+ element: name,
+ success: false,
+ error: error,
+ value: value
+ });
+ })
+ })
+ }
+
+ function getDeletePromise(targetProp, item) {
+ if (item) {
+ targetProp = targetProp + '/' + item;
+ }
+ return getUpdatePromise(targetProp, '');
+ }
+
+ var updates = [];
+ _.forIn(req.body, function (value, key) {
+ var data = {};
+ if (_.isObject(value)) {
+ if (value.type === 'leaf_list') {
+ _.forEach(value.data.remove, function (v) {
+ updates.push(getDeletePromise(key))
+ })
+ _.forEach(value.data.add, function (v) {
+ updates.push(getUpdatePromise(key, v))
+ })
+ } else if (value.type === 'leaf_empty') {
+ if (value.data) {
+ updates.push(getUpdatePromise(key, ' '))
+ } else {
+ updates.push(getDeletePromise(key))
+ }
+ }
+ } else {
+ updates.push(getUpdatePromise(key, value))
+ }
+ })
+
+ return new Promise(function (resolve, reject) {
+ Promise.all(updates).then(function (results) {
+ var response = {};
+ var output = {};
+ var hasError = false;
+ _.forEach(results, function (result) {
+ var record = {};
+ if (output[result.element]) {
+ if (_.isArray(output[result.element].value)) {
+ output[result.element].value.push(result.value);
+ } else {
+ output[result.element].value = [output[result.element].value, result.value];
+ }
+ } else {
+ output[result.element] = result;
+ }
+ hasError = hasError || !result.success
+ })
+ response.data = {
+ result: output,
+ hasError: hasError
+ };
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK;
+ console.log(response);
+ resolve(response);
+ }).catch(function (result) {
+ var response = {};
+ var error = {};
+ if (result.error['rpc-reply']) {
+ error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
+ error.message = result.error['rpc-reply']['rpc-error']['error-message'];
+ error.rpcError = result.error['rpc-reply']['rpc-error']
+ } else {
+ error.type = 'api-error';
+ error.message = 'invalid api call';
+ }
+ console.log('Problem with model update', error);
+ response.statusCode = error.statusCode || 500;
+ response.error = error;
+ reject(response);
+ });
+ });
+};
+
+remove = function (req) {
+ var backend = configuration.getBackendAPI();
+ var modelPath = req.query['path'];
+ var target = backend + '/config' + modelPath;
+ var requestHeaders = _.extend({},
+ constants.HTTP_HEADERS.accept.data,
+ constants.HTTP_HEADERS.content_type.data, {
+ 'Authorization': req.session && req.session.authorization
+ })
+ return new Promise(function (resolve, reject) {
+ rp({
+ url: target,
+ method: 'DELETE',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ }).then(function (response) {
+ return resolve({
+ statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+ data: modelPath
+ });
+ }).catch(function (result) {
+ var response = {};
+ var error = {};
+ if (result.error['rpc-reply']) {
+ error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
+ error.message = result.error['rpc-reply']['rpc-error']['error-message'];
+ error.rpcError = result.error['rpc-reply']['rpc-error']
+ } else {
+ error.type = 'api-error';
+ error.message = 'invalid api call';
+ }
+ console.log('Problem with model update', error);
+ response.statusCode = error.statusCode || 500;
+ response.error = error;
+ reject(response);
+ });
+ })
+}
\ No newline at end of file
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// DescriptorModelMeta API (NSD + VNFD)
+
+
+var ProjectManagement = {};
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var _ = require('lodash');
+var API_VERSION = 'v2';
+ProjectManagement.get = function(req, fields) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ // by default just load basic info as this request is expensive
+ fields = fields || ['name', 'description', 'project-config'];
+ var select = fields.length ? '?fields=' + fields.join(';') : '';
+
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ rp({
+ uri: `${utils.confdPort(api_server)}/${API_VERSION}/api/operational/project` + select,
+ method: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data']['project'] = JSON.parse(result[0].body)['rw-project:project'];
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with ProjectManagement.get', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to get ProjectManagement' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+ProjectManagement.create = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var data = req.body;
+ data = {
+ "project":[data]
+ }
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/project',
+ method: 'POST',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: data,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with ProjectManagement.create', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to create user' + error
+ };
+ reject(response);
+ });
+ });
+};
+ProjectManagement.update = function(req) {
+ //"rw-project:project"
+ var self = this;
+ var api_server = req.query['api_server'];
+ var bodyData = req.body;
+ // oddly enough, if we do not encode this here letting the request below does so incorrectly
+ var projectName = encodeURIComponent(bodyData.name);
+ var descriptionData = {
+ "rw-project:project" : {
+ "name": bodyData.name,
+ "description": bodyData.description
+ }
+ }
+ var updateTasks = [];
+ var baseUrl = utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/project/' + projectName
+ var updateProjectConfig = rp({
+ uri: baseUrl + '/project-config',
+ method: 'PUT',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: {
+ "project-config": bodyData['project-config']
+ },
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ });
+ updateTasks.push(updateProjectConfig);
+
+ var updateProjectDescription = rp({
+ uri: baseUrl + '/description',
+ method: 'PATCH',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: {"description": bodyData.description},
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ });
+ updateTasks.push(updateProjectDescription)
+ return new Promise(function(resolve, reject) {
+ Promise.all(
+ updateTasks
+ ).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with ProjectManagement.update', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to update project - ' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+ProjectManagement.delete = function(req) {
+ var self = this;
+ var projectname = encodeURIComponent(req.params.projectname);
+ var api_server = req.query["api_server"];
+ var requestHeaders = {};
+ var url = utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/project/' + projectname
+ return new Promise(function(resolve, reject) {
+ _.extend(requestHeaders,
+ constants.HTTP_HEADERS.accept.data,
+ constants.HTTP_HEADERS.content_type.data, {
+ 'Authorization': req.session && req.session.authorization
+ });
+ rp({
+ url: url,
+ method: 'DELETE',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ }, function(error, response, body) {
+ if (utils.validateResponse('ProjectManagement.DELETE', error, response, body, resolve, reject)) {
+ return resolve({
+ statusCode: response.statusCode,
+ data: JSON.stringify(response.body)
+ });
+ };
+ });
+ })
+}
+
+
+ProjectManagement.getPlatform = function(req, userId) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var user = req.params['userId'] || userId;
+ return new Promise(function(resolve, reject) {
+ var url = utils.confdPort(api_server) + '/' + API_VERSION + '/api/operational/rbac-platform-config';
+ if(user) {
+ url = url + '/user/' + encodeURIComponent(user);
+ }
+ Promise.all([
+ rp({
+ uri: url,
+ method: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ if(user) {
+ response['data']['platform'] = JSON.parse(result[0].body)['rw-rbac-platform:user'];
+ } else {
+ response['data']['platform'] = JSON.parse(result[0].body)['rw-rbac-platform:rbac-platform-config'];
+ }
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with ProjectManagement.getPlatform', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to get ProjectManagement.getPlatform' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+ProjectManagement.updatePlatform = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var bodyData = req.body;
+ data = bodyData;
+ data.user = JSON.parse(data.user)
+ var updateTasks = [];
+
+ var updatePlatform = rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/rbac-platform-config',
+ method: 'PUT',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: {
+ "rw-rbac-platform:rbac-platform-config": data
+ },
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ });
+ updateTasks.push(updatePlatform)
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ updateTasks
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with ProjectManagement.updatePlatform', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to update platform - ' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+
+module.exports = ProjectManagement;
url: uri + url + '?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
- 'Authorization': req.get('Authorization')
+ 'Authorization': req.session && req.session.authorization
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// DescriptorModelMeta API (NSD + VNFD)
+
+
+var Schema = {};
+var rp = require('request-promise');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var _ = require('lodash');
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var utils = require('../../api_utils/utils');
+var configuration = require('./configuration');
+
+var router = require('express').Router();
+
+
+router.use(bodyParser.json());
+router.use(cors());
+router.use(bodyParser.urlencoded({
+ extended: true
+}));
+
+router.get('/schema', cors(), function (req, res) {
+ getSchema(req).then(function (response) {
+ utils.sendSuccessResponse(response, res);
+ }, function (error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+module.exports = {
+ getRouter: function () {
+ return router;
+ },
+ init: function () {}
+};
+
+getSchema = function (req) {
+ var schemaURI = configuration.getBackendURL() + '/api/schema/';
+ var schemaPaths = req.query['request'];
+ var paths = schemaPaths.split(',');
+
+ function getSchemaRequest(path) {
+ return rp({
+ uri: schemaURI + path,
+ method: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ }
+
+ var requests = _.map(paths, getSchemaRequest);
+
+ return new Promise(function (resolve, reject) {
+ Promise.all(requests).then(
+ function (results) {
+ var data = {
+ schema: {}
+ }
+ _.forEach(results, function (result, index) {
+ data.schema[paths[index]] = JSON.parse(result.body);
+ });
+ resolve({
+ data: data,
+ statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+ });
+ }).catch(
+ function (error) {
+ var response = {};
+ console.log('Problem with schema.get', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to get schema' + error
+ };
+ reject(response);
+ });
+ });
+};
\ No newline at end of file
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * sessions api module. Provides API functions for sessions
+ * @module framework/core/modules/api/sessions
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+"use strict"
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var request = utils.request;
+var rp = require('request-promise');
+var sessionsAPI = {};
+var _ = require('lodash');
+var base64 = require('base-64');
+var APIVersion = '/v2';
+var configurationAPI = require('./configuration');
+var UserManagement = require('./userManagementAPI.js');
+var URL = require('url');
+
+// Used for determining what page a user should first go to.
+var Application = {
+ order: [
+ "rw-rbac-platform:super-admin",
+ "rw-rbac-platform:platform-admin",
+ "rw-rbac-platform:platform-oper",
+ "rw-project:project-admin",
+ "rw-project:project-oper",
+ "rw-project-mano:lcm-admin",
+ "rw-project-mano:lcm-oper",
+ "rw-project-mano:catalog-admin",
+ "rw-project-mano:catalog-oper",
+ "rw-project-mano:account-admin",
+ "rw-project-mano:account-oper"
+ ],
+ key: {
+ "rw-rbac-platform:super-admin": "user_management",
+ "rw-rbac-platform:platform-admin": "user_management",
+ "rw-rbac-platform:platform-oper": "user_management",
+ "rw-project:project-admin": "project_management",
+ "rw-project:project-oper": "project_management",
+ "rw-project-mano:catalog-admin": "composer",
+ "rw-project-mano:catalog-oper": "composer",
+ "rw-project-mano:lcm-admin": "launchpad",
+ "rw-project-mano:lcm-oper": "launchpad",
+ "rw-project-mano:account-admin": "accounts",
+ "rw-project-mano:account-oper": "accounts"
+ }
+};
+
+function logAndReject(mesg, reject, errCode) {
+ var res = {};
+ res.errorMessage = {
+ error: mesg
+ }
+ res.statusCode = errCode || constants.HTTP_RESPONSE_CODES.ERROR.BAD_REQUEST;
+ console.log(mesg);
+ reject(res);
+}
+
+function logAndRedirectToLogin(mesg, res, req, invalid) {
+ console.log(mesg);
+ if (!invalid) {
+ res.redirect(utils.buildRedirectURL(req, configurationAPI.globalConfiguration, 'login', '&referer=' + encodeURIComponent(req.headers.referer)));
+ }
+ res.end();
+}
+
+function logAndRedirectToEndSession(mesg, res, authorization, url) {
+ console.log(mesg);
+ res.set({
+ 'Authorization': authorization
+ });
+ res.redirect(url);
+ res.end();
+}
+var sessionPromiseResolve = null;
+sessionsAPI.sessionPromise = new Promise(function(resolve, reject) {
+ sessionPromiseResolve = resolve;
+});
+
+sessionsAPI.create = function (req, res) {
+ if (!req.session.passport){
+ logAndRedirectToLogin("lost session", res, req);
+ return new Promise(function (resolve, reject){reject("lost session")});
+ }
+ var api_server = req.query['api_server'] || (req.protocol + '://' + configurationAPI.globalConfiguration.get().api_server);
+ var uri = utils.confdPort(api_server);
+ var username = req.session.passport.user['username'];
+ var authorization_header_string = 'Bearer ' + req.session.passport.user.user.access_token;
+ return new Promise(function (resolve, reject) {
+ req.session.authorization = authorization_header_string;
+ req.session.api_server = api_server;
+ req.session.api_protocal = req.protocol;
+ req.session.loggedIn = true;
+ req.session.userdata = {
+ username: username,
+ };
+ UserManagement.getUserInfo(req, req.session.passport.user.username).then(function (results) {
+ var project_list_for_user = null;
+ if (!req.session.projectId && results.data.project) {
+ project_list_for_user = Object.keys(results.data.project);
+ if (project_list_for_user.length > 0) {
+ req.session.projectId = project_list_for_user.sort() && project_list_for_user[0];
+ }
+ }
+ sessionsAPI.setTopApplication(req);
+ req.session.isLCM = results.data.isLCM;
+
+ req.session['ui-state'] = results.data['ui-state'];
+ var lastActiveProject = req.session['ui-state'] && req.session['ui-state']['last-active-project'];
+ if (lastActiveProject) {
+ if (results.data.project.hasOwnProperty(lastActiveProject)) {
+ req.session.projectId = lastActiveProject;
+ }
+
+ }
+
+ var successMsg = 'User => ' + username + ' successfully logged in.';
+ successMsg += req.session.projectId ? 'Project => ' + req.session.projectId + ' set as default.' : '';
+
+ console.log(successMsg);
+
+ req.session.save(function (err) {
+ if (err) {
+ console.log('Error saving session to store', err);
+ }
+ // no response data, just redirect now that session data is set
+ if (req.session['ui-state'] && req.session['ui-state']['last-active-uri']) {
+ var url = URL.parse(req.session['ui-state']['last-active-uri']);
+ var host = req.headers.host;
+ var path = url.path;
+ var hash = url.hash;
+ var protocol = url.protocol;
+ var newUrl = protocol + '//' + host + path + (hash?hash:'');
+ console.log('Redirecting to: ' + newUrl)
+ res.redirect(newUrl)
+ } else {
+ if(req.session.topApplication) {
+ res.redirect(utils.buildRedirectURL(req, configurationAPI.globalConfiguration, req.session.topApplication));
+ } else {
+ res.redirect(utils.buildRedirectURL(req, configurationAPI.globalConfiguration, 'user_management', '#/user-profile'));
+ }
+ }
+ })
+
+ sessionPromiseResolve(req.session);
+
+ }).catch(function (error) {
+ // Something went wrong - Redirect to /login
+ var errorMsg = 'Error logging in or getting list of projects. Error: ' + error;
+ console.log(errorMsg);
+ logAndRedirectToLogin(errorMsg, res, req);
+ });
+ })
+};
+
+sessionsAPI.addProjectToSession = function (req, res) {
+ return new Promise(function (resolve, reject) {
+ if (req.session && req.session.loggedIn == true) {
+ Promise.all([UserManagement.getProfile(req), UserManagement.updateActiveProject(req)]).then(function () {
+ req.session.projectId = req.params.projectId;
+ req.session.topApplication = null;
+ sessionsAPI.setTopApplication(req, req.query.app);
+ req.session.save(function (err) {
+ if (err) {
+ console.log('Error saving session to store', err);
+ var errorMsg = 'Session does not exist or not logged in';
+ logAndReject(errorMsg, reject, constants.HTTP_RESPONSE_CODES.ERROR.NOT_FOUND);
+ } else {
+ var successMsg = 'Added project ' + req.session.projectId + ' to session ' + req.sessionID;
+ console.log(successMsg);
+ var response = {
+ statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+ data: JSON.stringify({
+ status: successMsg
+ })
+ }
+ return resolve(response);
+ }
+ // res.redirect('/');
+ });
+
+ })
+
+ }
+ });
+}
+
+sessionsAPI.delete = function (req, res) {
+ var idpServerAddress = configurationAPI.globalConfiguration.get().idp_server_address;
+ var idpServerProtocol = configurationAPI.globalConfiguration.get().idp_server_protocol;
+ var idpServerPortNumber = configurationAPI.globalConfiguration.get().idp_server_port_number;
+ var idpEndSessionPath = constants.END_SESSION_PATH;
+ var url = idpServerProtocol + '://' +
+ idpServerAddress + ':' +
+ idpServerPortNumber + '/' +
+ idpEndSessionPath;
+ var authorization = req.session.authorization;
+ return new Promise(function (resolve, reject) {
+ Promise.all([
+ UserManagement.updateActiveUri(req),
+ new Promise(function (success, failure) {
+ req.session.destroy(function (err) {
+ if (err) {
+ var errorMsg = 'Error deleting session. Error: ' + err;
+ console.log(errorMsg);
+ success({
+ status: 'error',
+ message: errorMsg
+ });
+ }
+
+ var successMsg = 'Success deleting session';
+ console.log(successMsg);
+
+ success({
+ status: 'success',
+ message: successMsg
+ });
+ });
+ })
+ ]).then(function (result) {
+ // assume the session was deleted!
+ var message = 'Session was deleted. Redirecting to end_session';
+ resolve({
+ statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+ data: {
+ url: url,
+ message: message
+ }
+ });
+
+ }).catch(function (error) {
+ var message = "An error occured while deleting session";
+ resolve({
+ statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
+ data: {
+ url: url,
+ message: message
+ }
+ });
+ });
+ });
+}
+
+sessionsAPI.setTopApplication = function (req, suggestedPlugin) {
+ var selectedProject = req.session.projectId;
+ var userProject = selectedProject ? req.session.projectMap[selectedProject] : null;
+ if (userProject) {
+ if (suggestedPlugin) {
+ if (req.session.platformMap['rw-rbac-platform:super-admin']) {
+ topApplication = suggestedPlugin;
+ } else {
+ var roles = _.reduce(Object.keys(Application.key), function (accumulator, role) {
+ if (Application.key[role] === suggestedPlugin) {
+ accumulator.push(role);
+ }
+ return accumulator;
+ }, []);
+ if (_.some(roles, function (role){return userProject.role[role]})) {
+ req.session.topApplication = suggestedPlugin;
+ return;
+ }
+ }
+ }
+ _.some(Application.order, function (role) {
+ if (userProject.role[role] || req.session.platformMap.role[role]) {
+ req.session.topApplication = Application.key[role];
+ return true;
+ }
+ return false;
+ })
+ }
+}
+
+module.exports = sessionsAPI;
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// DescriptorModelMeta API (NSD + VNFD)
+
+
+var UserManagement = {};
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var Promise = require('promise');
+var constants = require('../../api_utils/constants');
+var utils = require('../../api_utils/utils');
+var _ = require('lodash');
+var ProjectManagementAPI = require('./projectManagementAPI.js');
+var API_VERSION = 'v2';
+
+UserManagement.get = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+
+ return new Promise(function(resolve, reject) {
+ var userConfig = rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/operational/user-config/user',
+ method: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ });
+ var userOp = rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/operational/user-state/user',
+ method: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ Promise.all([
+ userConfig,
+ userOp
+ ]).then(function(result) {
+ var response = {};
+ var userConfig = [];
+ var userOpData = {};
+ response['data'] = {};
+ if (result[0].body) {
+ userConfig = JSON.parse(result[0].body)['rw-user:user'];
+ }
+ if (result[1].body) {
+ JSON.parse(result[1].body)['rw-user:user'].map(function(u) {
+ userOpData[u['user-domain'] + ',' + u['user-name']] = u;
+ })
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+ response['data']['user'] = userConfig.map(function(u,i) {
+ var mergedData = _.merge(u, userOpData[u['user-domain'] + ',' + u['user-name']]);
+ mergedData.projects = {
+ ids: [],
+ data: {}
+ };
+ var projects = mergedData.projects;
+ mergedData.role && mergedData.role.map(function(r) {
+ if ((r.role != "rw-project:user-self" )&& (r.role != "rw-rbac-platform:user-self")) {
+ var projectId = r.keys.split(';')[0];
+ if (projectId == "") {
+ projectId = "platform"
+ }
+ if (!projects.data[projectId]) {
+ projects.ids.push(projectId);
+ projects.data[projectId] = [];
+ }
+ projects.data[projectId].push(r.role);
+ }
+ })
+ return mergedData;
+ })
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with UserManagement.get', error);
+ response.statusCode = error.statusCode || constants.HTTP_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR;
+ response.errorMessage = {
+ error: 'Failed to get UserManagement' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+
+UserManagement.getProfile = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ return new Promise(function(resolve, reject) {
+ var response = {};
+ try {
+ var userId = req.session.userdata.username
+ response['data'] = {
+ userId: userId,
+ projectId: req.session.projectId,
+ domain: req.session.passport.user.domain
+ };
+ UserManagement.getUserInfo(req, userId).then(function(result) {
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK;
+ response.data.data = result.data
+ resolve(response);
+ }, function(error) {
+ console.log('Error retrieving getUserInfo');
+ response.statusCode = constants.HTTP_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR;
+ reject(response);
+ })
+ } catch (e) {
+ var response = {};
+ console.log('Problem with UserManagement.get', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to get UserManagement' + error
+ };
+ reject(response);
+ }
+ });
+};
+UserManagement.getUserInfo = function(req, userId, domain) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var id = req.params['userId'] || userId;
+ var domain = req.params['domainId'] || domain;
+ var response = {};
+ return new Promise(function(resolve, reject) {
+ if (id) {
+ var getProjects = ProjectManagementAPI.get(req, ['name', 'project-config']);
+ var getPlatformUser = ProjectManagementAPI.getPlatform(req, id);
+ var getUserUiState = UserManagement.getUserUiState(req);
+ Promise.all([
+ getProjects,
+ getPlatformUser,
+ getUserUiState
+ ]).then(function(result) {
+ var userData = {
+ platform: {
+ role: {
+
+ }
+ },
+ //id/key values for each project
+ projectId:[],
+ project: {
+ /**
+ * [projectId] : {
+ * data: [project object],
+ * role: {
+ * [roleId]: true
+ * }
+ * }
+ */
+ }
+ }
+ //Build UI state
+ var uiState = result[2].data && result[2].data['rw-user:user'];
+ userData['ui-state'] = uiState['ui-state'];
+ //Build platform roles
+ var platformRoles = result[1].data.platform && result[1].data.platform.role;
+ platformRoles && platformRoles.map(function(r) {
+ userData.platform.role[r.role] = true
+ });
+ //Build project roles
+ var projects = result[0].data.project;
+ var userProjects = [];
+ projects && projects.map(function(p, i) {
+ userData.project[p.name] = {
+ data: p,
+ role: {}
+ }
+ userData.projectId.push(p.name);
+ if (userData.platform.role['rw-rbac-platform:super-admin']) {
+ userData.project[p.name] = {
+ data: p,
+ role: {
+ "rw-project:project-admin": true,
+ "rw-project:project-oper": true,
+ "rw-project-mano:account-admin": true,
+ "rw-project-mano:account-oper": true,
+ "rw-project-mano:catalog-admin": true,
+ "rw-project-mano:catalog-oper": true,
+ "rw-project-mano:lcm-admin": true,
+ "rw-project-mano:lcm-oper": true
+ }
+ }
+ } else {
+ var users = p['project-config'] && p['project-config'].user;
+ users && users.map(function(u) {
+ if(u['user-name'] == id) {
+ u.role && u.role.map(function(r) {
+ userData.project[p.name].role[r.role] = true;
+ if (r.role === 'rw-project:project-admin') {
+ userData.project[p.name].role["rw-project-mano:account-admin"] = true;
+ userData.project[p.name].role["rw-project-mano:catalog-admin"] = true;
+ userData.project[p.name].role["rw-project-mano:lcm-admin"] = true;
+ userData.isLCM = true;
+ } else if (r.role === 'rw-project:project-oper') {
+ userData.project[p.name].role["rw-project-mano:account-oper"] = true;
+ userData.project[p.name].role["rw-project-mano:catalog-oper"] = true;
+ userData.project[p.name].role["rw-project-mano:lcm-oper"] = true;
+ userData.isLCM = true;
+ }
+ });
+ u["rw-project-mano:mano-role"] && u["rw-project-mano:mano-role"] .map(function(r) {
+ userData.project[p.name].role[r.role] = true;
+ if (r.role.indexOf('rw-project-mano:lcm') > -1) {
+ userData.isLCM = true;
+ }
+ });
+ }
+ })
+ }
+ });
+ response.data = userData;
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK;
+
+ req.session.projectMap = userData.project;
+ req.session.platformMap = userData.platform;
+ resolve(response);
+ })
+ } else {
+ var errorMsg = 'userId not specified in UserManagement.getUserInfo';
+ console.error(errorMsg);
+ response.statusCode = constants.HTTP_RESPONSE_CODES.ERROR.BAD_REQUEST;
+ response.error = errorMsg;
+ reject(response)
+ }
+
+ })
+}
+UserManagement.create = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var data = req.body;
+ data = {
+ "user":[data]
+ }
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/user-config',
+ method: 'POST',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: data,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with UserManagement.create', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to create user' + error
+ };
+ reject(response);
+ });
+ });
+};
+UserManagement.update = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var bodyData = req.body;
+ data = {
+ "rw-user:user": bodyData
+ }
+ var updateTasks = [];
+ if(bodyData.hasOwnProperty('old-password')) {
+ var changePW = rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/operations/change-password',
+ method: 'POST',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: {
+ "input": {
+ 'user-name' : bodyData['user-name'],
+ 'user-domain' : bodyData['user-domain'],
+ 'old-password' : bodyData['old-password'],
+ 'new-password' : bodyData['new-password'],
+ 'confirm-password' : bodyData['confirm-password'],
+ }
+ },
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ });
+ updateTasks.push(changePW);
+ };
+ var updateUser = rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/user-config/user/' + encodeURIComponent(bodyData['user-name']) + ',' + encodeURIComponent(bodyData['user-domain']),
+ method: 'PUT',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: data,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ });
+ updateTasks.push(updateUser)
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ updateTasks
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with UserManagement.passwordChange', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to passwordChange user' + error
+ };
+ reject(response);
+ });
+ });
+};
+
+UserManagement.delete = function(req) {
+ var self = this;
+ var username = req.params.username;
+ var domain = req.params.domain;
+ var api_server = req.query["api_server"];
+ var requestHeaders = {};
+ var url = `${utils.confdPort(api_server)}/${API_VERSION}/api/config/user-config/user/${encodeURIComponent(username)},${encodeURIComponent(domain)}`
+ return new Promise(function(resolve, reject) {
+ _.extend(requestHeaders,
+ constants.HTTP_HEADERS.accept.data,
+ constants.HTTP_HEADERS.content_type.data, {
+ 'Authorization': req.session && req.session.authorization
+ });
+ rp({
+ url: url,
+ method: 'DELETE',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ }, function(error, response, body) {
+ if (utils.validateResponse('UserManagement.DELETE', error, response, body, resolve, reject)) {
+ return resolve({
+ statusCode: response.statusCode,
+ data: JSON.stringify(response.body)
+ });
+ };
+ });
+ })
+};
+UserManagement.getUserUiState = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var user = req.session.passport.user;
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/user-config/user/'+encodeURIComponent(user.username) + ',' + encodeURIComponent(user.domain),
+ method: 'GET',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = JSON.parse(result[0].body);
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with UserManagement.getUserUiState', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to create user' + error
+ };
+ reject(response);
+ });
+ });
+};
+UserManagement.updateActiveProject = function(req) {
+ var self = this;
+ var api_server = req.query['api_server'];
+ var user = req.session.passport.user;
+ var data = {
+ "rw-user:user-config": {
+ "user":{
+ "user-name" : user.username,
+ "user-domain": user.domain,
+ "ui-state": {
+ "last-active-project" : req.params.projectId
+ }
+ }
+ }
+ }
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/user-config',
+ method: 'PATCH',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: data,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with UserManagement.updateActiveProject', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to create user' + error
+ };
+ reject(response);
+ });
+ });
+};
+UserManagement.updateActiveUri = function(req) {
+ if (!req.session.passport) {
+ console.debug("passport gone before we got the save the active uri");
+ var response = {
+ statusCode: 500,
+ errorMessage: {
+ error: 'Failed to save active uri'
+ }};
+ return Promise.resolve(response);
+ }
+ var self = this;
+ var api_server = req.query['api_server'];
+ var user = req.session.passport.user;
+ var ref = req.headers.referer;
+ var hash = req.query.hash;
+ var data = {
+ "rw-user:user-config": {
+ "user":{
+ "user-name" : user.username,
+ "user-domain": user.domain,
+ "ui-state": {
+ "last-active-uri" : ref + decodeURIComponent(hash)
+ }
+ }
+ }
+ }
+ return new Promise(function(resolve, reject) {
+ Promise.all([
+ rp({
+ uri: utils.confdPort(api_server) + '/' + API_VERSION + '/api/config/user-config',
+ method: 'PATCH',
+ headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
+ 'Authorization': req.session && req.session.authorization
+ }),
+ forever: constants.FOREVER_ON,
+ json: data,
+ rejectUnauthorized: false,
+ resolveWithFullResponse: true
+ })
+ ]).then(function(result) {
+ var response = {};
+ response['data'] = {};
+ if (result[0].body) {
+ response['data'] = result[0].body;
+ }
+ response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK
+
+ resolve(response);
+ }).catch(function(error) {
+ var response = {};
+ console.log('Problem with UserManagement.updateActiveProject', error);
+ response.statusCode = error.statusCode || 500;
+ response.errorMessage = {
+ error: 'Failed to create user' + error
+ };
+ reject(response);
+ });
+ });
+};
+module.exports = UserManagement;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
if (!NAVIGATION[plugin_name]) {
NAVIGATION[plugin_name] = {};
}
-
if (!NAVIGATION[plugin_name].routes) {
NAVIGATION[plugin_name].routes = routes;
} else {
NAVIGATION[plugin_name].label = label || 'RW.UI Plugin';
}
+function addAllow(plugin_name, allow) {
+ if (!NAVIGATION[plugin_name]) {
+ NAVIGATION[plugin_name] = {};
+ }
+ NAVIGATION[plugin_name].allow = allow || '*';
+}
+
+function addAdminFlag(plugin_name, admin_link) {
+ if (!NAVIGATION[plugin_name]) {
+ NAVIGATION[plugin_name] = {};
+ }
+ NAVIGATION[plugin_name].admin_link = admin_link || false;
+}
+
function getNavigation() {
return NAVIGATION;
}
addOrder(plugin_name, plugin.order);
addPriority(plugin_name, plugin.priority);
addLabel(plugin_name, plugin.name);
+ addAllow(plugin_name, plugin.allow);
+ addAdminFlag(plugin_name, plugin.admin_link);
}
function init() {
--- /dev/null
+
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * auth routes module. Provides a RESTful API for this
+ * skyquake instance's auth state.
+ * @module framework/core/modules/routes/auth
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+var configurationAPI = require('../api/configuration');
+
+var auth = {};
+
+auth.routes = function(authManager) {
+ console.log('Configuring auth routes');
+ Router.use(bodyParser.json());
+ Router.use(cors());
+ Router.use(bodyParser.urlencoded({
+ extended: true
+ }));
+
+ // Define routes.
+ Router.get('/', function(req, res) {
+ var default_page = null;
+ var api_server = req.query['api_server'] || (req.protocol + '://' + configurationAPI.globalConfiguration.get().api_server);
+ if (req.session && req.session.topApplication) {
+ default_page = utils.buildRedirectURL(req, configurationAPI.globalConfiguration, req.session.topApplication);
+ } else {
+ default_page = utils.buildRedirectURL(req, configurationAPI.globalConfiguration, 'user_management', '#/user-profile');
+ }
+ if (!req.user) {
+ res.redirect('/login');
+ } else {
+ res.redirect(default_page);
+ }
+ });
+
+ Router.get('/login', cors(), function(req, res) {
+ // res.render('login.html');
+ res.redirect('/login/idp');
+ });
+
+ Router.get('/login/idp',
+ authManager.passport.authenticate('oauth2')
+ );
+
+ Router.get('/callback', function(req, res, next) {
+ authManager.passport.authenticate('oauth2', function(err, user, info) {
+ if (err) {
+ // Catch some errors specific to deployments (e.g. IDP unavailable)
+ if (err.oauthError && err.oauthError.code == 'ENOTFOUND') {
+ return res.render('idpconnectfail.ejs', {
+ callback_url: req.url
+ });
+ }
+ return res.redirect('/login');
+ }
+ if (!user) {
+ return res.redirect('/login');
+ }
+ req.logIn(user, function(err) {
+ if (err) {
+ return next(err);
+ }
+ return res.redirect('/session?redirectParams=' + req.url);
+ });
+ })(req, res, next);
+ });
+
+
+ Router.get('/login.html', cors(), function(req, res) {
+ res.render('login.html');
+ });
+}
+
+auth.router = Router;
+
+module.exports = auth;
});
});
-Router.get('/check-auth', function(req, res) {
- console.log('testing auth')
- var api_server = req.query["api_server"];
- var uri = utils.confdPort(api_server) + '/api/config/';
-
- checkAuth(uri, req).then(function(data) {
- utils.sendSuccessResponse(data, res);
- }, function(error) {
- utils.sendErrorResponse(error, res);
- });
-});
-
-function checkAuth(uri, req){
- return new Promise(function(resolve, reject) {
- request({
- uri: uri,
- method: 'GET',
- headers: _.extend({}, {
- 'Authorization': req.get('Authorization'),
- forever: CONSTANTS.FOREVER_ON,
- rejectUnauthorized: false,
- })
- }, function(error, response, body) {
- console.log(arguments)
- if( response.statusCode == 401) {
- reject({statusCode: 401, error: response.body});
- } else {
- resolve({statusCode:200, data:response.body})
- }
- });
- });
-}
-
module.exports = Router;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
var Router = require('express').Router();
var utils = require('../../api_utils/utils');
var configurationAPI = require('../api/configuration');
+var csrfCheck = require('../../api_utils/csrf').csrfCheck;
Router.use(bodyParser.json());
Router.use(cors());
extended: true
}));
-Router.get('/', cors(), function(req, res, next) {
- res.redirect('/launchpad/?api_server=' + req.protocol + '://' + configurationAPI.globalConfiguration.get().api_server + '&upload_server=' + req.protocol + '://' + (configurationAPI.globalConfiguration.get().upload_server || req.hostname));
+//Should have a way of adding excluded routes to this via plugin registry, instead of hard coding
+Router.use(/^(?!.*(login\/idp|session|composer\/upload|composer\/update)).*/, function(req, res, next) {
+ var api_server = req.query['api_server'] || (req.protocol + '://' + configurationAPI.globalConfiguration.get().api_server);
+ if (req.session && req.session.loggedIn) {
+ switch (req.method) {
+ case 'POST':
+ case 'PUT':
+ csrfCheck(req, res, next);
+ break;
+ default:
+ next();
+ break;
+ }
+ } else {
+ console.log('Redirect to login.html');
+ res.redirect(utils.buildRedirectURL(req, configurationAPI.globalConfiguration, 'login', '&referer=' + encodeURIComponent(req.headers.referer)));
+ }
});
+
Router.get('/nav', cors(), function(req, res) {
- navAPI.get(req).then(function(data) {
- utils.sendSuccessResponse(data, res);
- }, function(error) {
- utils.sendErrorResponse(error, res);
- });
+ navAPI.get(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
});
Router.get('/nav/:plugin_id', cors(), function(req, res) {
- navAPI.get(req).then(function(data) {
- utils.sendSuccessResponse(data, res);
- }, function(error) {
- utils.sendErrorResponse(error, res);
- });
+ navAPI.get(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
});
Router.post('/nav/:plugin_id', cors(), function(req, res) {
- navAPI.create(req).then(function(data) {
- utils.sendSuccessResponse(data, res);
- }, function(error) {
- utils.sendErrorResponse(error, res);
- });
+ navAPI.create(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
});
Router.put('/nav/:plugin_id/:route_id', cors(), function(req, res) {
- navAPI.update(req).then(function(data) {
- utils.sendSuccessResponse(data, res);
- }, function(error) {
- utils.sendErrorResponse(error, res);
- });
+ navAPI.update(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
});
Router.delete('/nav/:plugin_id/:route_id', cors(), function(req, res) {
- navAPI.delete(req).then(function(data) {
- utils.sendSuccessResponse(data, res);
- }, function(error) {
- utils.sendErrorResponse(error, res);
- });
+ navAPI.delete(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
});
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * inactivity routes module. Provides a RESTful API for this
+ * skyquake instance's inactivity state.
+ * @module framework/core/modules/routes/inactivity
+ * @author Laurence Maultsby <laurence.maultsby@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+var ProjectManagementAPI = require('../api/projectManagementAPI.js');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+ extended: true
+}));
+
+Router.get('/project', cors(), function(req, res) {
+ ProjectManagementAPI.get(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+Router.post('/project', cors(), function(req, res) {
+ ProjectManagementAPI.create(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+Router.put('/project', cors(), function(req, res) {
+ ProjectManagementAPI.update(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+Router.delete('/project/:projectname', cors(), function(req, res) {
+ ProjectManagementAPI.delete(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+Router.put('/platform', cors(), function(req, res) {
+ ProjectManagementAPI.updatePlatform(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+Router.get('/platform', cors(), function(req, res) {
+ ProjectManagementAPI.getPlatform(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+module.exports = Router;
+
+
+
--- /dev/null
+
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * Node sessions routes module.
+ * Provides a RESTful API to manage sessions.
+ * @module framework/core/modules/routes/sessions
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var sessionsAPI = require('../api/sessions');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+var CONSTANTS = require('../../api_utils/constants.js');
+var request = require('request');
+var _ = require('lodash');
+
+var sessions = {};
+
+sessions.routes = function(sessionsConfig) {
+ Router.use(bodyParser.json());
+ Router.use(cors());
+ Router.use(bodyParser.urlencoded({
+ extended: true
+ }));
+
+ // Overloaded get method to handle OpenIDConnect redirect to establish a session.
+ Router.get('/session*', cors(), /*sessionsConfig.authManager.passport.authenticate('main', {
+ noredirect: false
+ }), */function(req, res) {
+ req.query['api_server'] = sessionsConfig.api_server_protocol + '://' + sessionsConfig.api_server;
+ sessionsAPI.create(req, res).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ });
+ });
+
+ // For project switcher UI
+ Router.put('/session/:projectId', cors(), function(req, res) {
+ sessionsAPI.addProjectToSession(req, res).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+ });
+
+ Router.delete('/session', cors(), function(req, res) {
+ sessionsAPI.delete(req, res).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ });
+ });
+}
+
+sessions.router = Router;
+
+
+module.exports = sessions;
--- /dev/null
+
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * inactivity routes module. Provides a RESTful API for this
+ * skyquake instance's inactivity state.
+ * @module framework/core/modules/routes/inactivity
+ * @author Laurence Maultsby <laurence.maultsby@riftio.com>
+ */
+
+var cors = require('cors');
+var bodyParser = require('body-parser');
+var Router = require('express').Router();
+var utils = require('../../api_utils/utils');
+var UserManagementAPI = require('../api/userManagementAPI.js');
+
+Router.use(bodyParser.json());
+Router.use(cors());
+Router.use(bodyParser.urlencoded({
+ extended: true
+}));
+
+Router.get('/user', cors(), function(req, res) {
+ UserManagementAPI.get(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ 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.get('/user-data/:userId/:domain?', cors(), function(req, res) {
+ UserManagementAPI.getUserInfo(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);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+Router.put('/user', cors(), function(req, res) {
+ UserManagementAPI.update(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+Router.delete('/user/:username/:domain', cors(), function(req, res) {
+ UserManagementAPI.delete(req).then(function(response) {
+ utils.sendSuccessResponse(response, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+});
+
+module.exports = Router;
+
+
+
--- /dev/null
+<% if (!user) { %>
+ <p>Welcome! Please <a href="/login">log in</a>.</p>
+<% } else { %>
+ <p>Hello, <%= user.username %>. View your <a href="<%= default_page %>">default page</a>. TODO: Update link to dashboard</p>
+<% } %>
\ No newline at end of file
--- /dev/null
+<style type="text/css">
+
+html {
+ background: #f1f1f1;
+}
+
+body {
+ background: #f1f1f1;
+}
+#idpfail {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ align-items: center;
+}
+#idpfail .message {
+ display: flex;
+ margin-bottom: 20px;
+ font-size: 1.625rem;
+ font-weight: 400;
+ text-decoration: none;
+ text-transform: uppercase;
+ font-family: roboto-thin, Helvetica, Arial, sans-serif;
+ color: #CD5C5C;
+}
+#retrylink {
+ margin-top:40px;
+ font-family: roboto-thin, Helvetica, Arial, sans-serif;
+}
+
+
+</style>
+<div id="idpfail">
+ <p class="message">
+ We are having trouble connecting to the Identity Provider.
+ </p>
+ <p class="message">
+ Please check that it is running and reachable.
+ </p>
+ <p id="retrylink">
+ Once you have resolved the connectivity issues, <a href="<%= callback_url %>">please click here to retry.</a>
+ </p>
+</div>
\ No newline at end of file
--- /dev/null
+<style>
+ html {
+ display: none;
+ }
+</style>
+<script>
+ if (self == top) {
+ document.documentElement.style.display = 'block';
+ } else {
+ top.location = self.location;
+ }
+</script>
+<div id="app"></div>
\ No newline at end of file
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import appConfiguration from '../utils/appConfiguration'
+
+let versionKeyPrefix = null;
+
+const localCache = new class {
+ get(key) {
+ let valueAsString = localStorage.getItem(key);
+ return valueAsString ? JSON.parse(valueAsString) : undefined;
+ }
+ set(key, val) {
+ localStorage.setItem(key, typeof val === 'string' ? val : JSON.stringify(val));
+ }
+}();
+
+let objCache = new Map();
+
+const storeCache = new class {
+ get(key) {
+ if (objCache[key]) {
+ objCache[key].timerId && clearTimeout(objCache[key].timerId)
+ objCache[key].timerId = setTimeout((key) => delete objCache[key], 2000)
+ return objCache[key].value;
+ }
+ const obj = localCache.get(key);
+ if (obj) {
+ objCache[key] = {
+ value: obj,
+ timerId: setTimeout((key) => delete objCache[key], 2000)
+ }
+ return obj;
+ }
+ }
+ set(key, obj) {
+ setTimeout(localCache.set, 100, key, obj);
+ objCache[key] = {
+ value: obj,
+ timerId: setTimeout((key) => delete objCache[key], 2000)
+ }
+ }
+ init(version) {
+ versionKeyPrefix = 's-v-' + version;
+ const currentStoreVersion = localStorage.getItem('store-version');
+ if (currentStoreVersion !== version) {
+ let removeItems = [];
+ for (let i = 0; i < localStorage.length; ++i) {
+ let key = localStorage.key(i);
+ if (key.startsWith('s-v-')) {
+ removeItems.push(key);
+ }
+ }
+ removeItems.forEach((key) => localStorage.removeItem(key));
+ localStorage.setItem('store-version', version);
+ }
+ }
+}();
+
+class StoreCache {
+ constructor(name) {
+ this.name = 's-v-' + name;
+ }
+ get(key) {
+ return storeCache.get(this.name + key);
+ }
+ set(key, obj) {
+ storeCache.set(this.name + key, obj);
+ }
+ init() {
+ return versionKeyPrefix ? Promise.resolve() : new Promise(
+ (resolve, reject) => {
+ appConfiguration.get().then((config) => {
+ storeCache.init(config.version);
+ resolve();
+ })
+ }
+ )
+ }
+}
+
+module.exports = StoreCache;
\ No newline at end of file
--- /dev/null
+import modelActions from './modelActions'
+import modelSource from './modelSource'
+
+export {
+ modelSource,
+ modelActions
+}
\ No newline at end of file
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+
+class Actions {
+
+ constructor() {
+ this.generateActions(
+ 'loadModel',
+ 'processRequestSuccess',
+ 'processRequestInitiated',
+ 'processRequestFailure');
+ }
+}
+
+export default Alt.createActions(Actions);
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import rw from 'utils/rw'
+import modelActions from './modelActions'
+import Utils from 'utils/utils'
+import $ from 'jquery';
+
+const source = {
+ loadModel: function () {
+ return {
+ remote: function (state, path) {
+ return new Promise(function (resolve, reject) {
+ $.ajax({
+ url: '/model?path=' + path,
+ type: 'GET',
+ success: function (result) {
+ resolve(result);
+ },
+ error: function (xhr, errorType, errorMessage) {
+ console.log("There was an error updating the model: ", errorType, errorMessage, xhr);
+ reject({response: xhr.responseJSON, errorType, errorMessage});
+ }
+ });
+ })
+ },
+ success: modelActions.processRequestSuccess,
+ loading: modelActions.processRequestInitiated,
+ error: modelActions.processRequestFailure
+ }
+ },
+ updateModel: function () {
+ return {
+ remote: function (state, path, data) {
+ const url = path.reduce((url, node) => {
+ url += node[0] !== '[' ? '/' : '';
+ return url + node
+ }, `/model?path=/${state.path}`);
+ return new Promise(function (resolve, reject) {
+ $.ajax({
+ url: url,
+ type: 'PATCH',
+ data: data,
+ success: function (result) {
+ resolve(result);
+ },
+ error: function (xhr, errorType, errorMessage) {
+ console.log("There was an error updating the model: ", errorType, errorMessage, xhr);
+ reject({response: xhr.responseJSON, errorType, errorMessage});
+ }
+ });
+ })
+ },
+ success: modelActions.processRequestSuccess,
+ loading: modelActions.processRequestInitiated,
+ error: modelActions.processRequestFailure
+ }
+ },
+ createModel: function () {
+ return {
+ remote: function (state, path, data) {
+ const url = path.reduce((url, node) => {
+ url += node[0] !== '[' ? '/' : '';
+ return url + node
+ }, `/model?path=/${state.path}`);
+ return new Promise(function (resolve, reject) {
+ $.ajax({
+ url: url,
+ type: 'PUT',
+ data: data,
+ success: function (result) {
+ resolve(result);
+ },
+ error: function (xhr, errorType, errorMessage) {
+ console.log("There was an error updating the model: ", errorType, errorMessage, xhr);
+ reject({response: xhr.responseJSON, errorType, errorMessage});
+ }
+ });
+ })
+ },
+ success: modelActions.processRequestSuccess,
+ loading: modelActions.processRequestInitiated,
+ error: modelActions.processRequestFailure
+ }
+ },
+
+ deleteModel: function () {
+ return {
+ remote: function (state, path) {
+ const url = path.reduce((url, node) => {
+ url += node[0] !== '[' ? '/' : '';
+ return url + node
+ }, `/model?path=/${state.path}`);
+ return new Promise(function (resolve, reject) {
+ $.ajax({
+ url: url,
+ type: 'DELETE',
+ success: function (result) {
+ resolve(result);
+ },
+ error: function (xhr, errorType, errorMessage) {
+ console.log("There was an error updating the model: ", errorType, errorMessage, xhr);
+ reject({response: xhr.responseJSON, errorType, errorMessage});
+ }
+ });
+ })
+ },
+ success: modelActions.processRequestSuccess,
+ loading: modelActions.processRequestInitiated,
+ error: modelActions.processRequestFailure
+ }
+ }
+}
+module.exports = source;
\ No newline at end of file
--- /dev/null
+import schemaActions from './schemaActions'
+import schemaSource from './schemaSource'
+
+export {
+ schemaSource,
+ schemaActions
+}
\ No newline at end of file
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import Alt from 'widgets/skyquake_container/skyquakeAltInstance';
+
+class Actions {
+
+ constructor() {
+ this.generateActions(
+ 'loadSchema',
+ 'loadSchemaSuccess',
+ 'loadSchemaLoading',
+ 'loadSchemaFail');
+ }
+}
+
+export default Alt.createActions(Actions);
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import rw from 'utils/rw'
+import schemaActions from './schemaActions'
+import Utils from 'utils/utils'
+import $ from 'jquery';
+import StoreCache from '../SourceCache'
+
+const storeCache = new StoreCache('schema');
+storeCache.init(); // get the ball rolling
+
+function getCachedSchema(request) {
+ const cachedSchema = {};
+ const requestSchema = [];
+ request.forEach((path) => {
+ let schema = storeCache.get(path);
+ if (schema) {
+ cachedSchema[path] = schema
+ } else {
+ requestSchema.push(path);
+ }
+ });
+ return {
+ cachedSchema,
+ requestSchema
+ };
+}
+
+const schemaSource = {
+ loadSchema: function () {
+ return {
+ local: function (state, request) {
+ request = Array.isArray(request) ? request : [request];
+ const results = getCachedSchema(request);
+ if (!results.requestSchema.length) {
+ return(Promise.resolve(results.cachedSchema));
+ }
+ },
+
+ remote: function (state, request) {
+ return new Promise(function (resolve, reject) {
+ storeCache.init().then(() => {
+ request = Array.isArray(request) ? request : [request];
+ const results = getCachedSchema(request);
+ if (!results.requestSchema.length) {
+ resolve({
+ schema: results.cachedSchema
+ });
+ } else {
+ $.ajax({
+ url: '/schema?request=' + results.requestSchema.join(','),
+ type: 'GET',
+ success: function ({
+ schema
+ }) {
+ for (let path in schema) {
+ storeCache.set(path, schema[path]);
+ }
+ resolve(getCachedSchema(request).cachedSchema);
+ },
+ error: function (error) {
+ console.log("There was an error getting the schema: ", error);
+ reject(error);
+ }
+ }).fail(function (xhr) {
+ console.log("There was an error getting the schema: ", xhr);
+ Utils.checkAuthentication(xhr.status);
+ reject("There was an error getting the schema.")
+ });
+ }
+ })
+ })
+ },
+ success: schemaActions.loadSchemaSuccess,
+ loading: schemaActions.loadSchemaLoading,
+ error: schemaActions.loadSchemaFail
+ }
+ },
+}
+export default schemaSource;
\ No newline at end of file
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
$error-red:#FF5F5F;
-//PC
+/*PC*/
$black: #000;
$gray-lightest: #f1f1f1;
$gray-darker: #666;
$gray-darkest: #333;
$white: #FFF;
-//
-// Brand Colors
-//
+/**/
+/* Brand Colors*/
+/**/
$brand-blue-light: #30baef;
$brand-blue: #00acee;
$brand-blue-dark: #147ca3;
$neutral-light-4: hsl(360, 100%, 50%);
$neutral-light-5: hsl(360, 100%, 50%);
-$neutral-dark-1: hsl(360, 100%, 50%);
-$neutral-dark-2: hsl(360, 100%, 50%);
-$neutral-dark-3: hsl(360, 100%, 50%);
-$neutral-dark-4: hsl(360, 100%, 50%);
-$neutral-dark-5: hsl(360, 100%, 50%);
+$neutral-dark-0: hsl(0, 0%, 80.7%);
+$neutral-dark-1: hsl(0, 0%, 63.7%);
+$neutral-dark-2: hsl(0, 0%, 56.7%);
+$neutral-dark-3: hsl(0, 0%, 49.7%);
+$neutral-dark-4: hsl(0, 0%, 42.7%);
+$neutral-dark-5: hsl(0, 0%, 35.7%);
$netral-black: hsl(0, 100%, 0%);
*
*/
/*@import "./vendor/css-reset-2.0/css-reset.css";*/
-@import "../../node_modules/reset-css/reset.css";
-
.has-drop-shadow {
box-shadow: 2px 2px rgba(0, 0, 0, .15)
}
margin-top: 150px;
margin-bottom: 20px;
background-size: 154px 102px;
- /*background-image: url(./img/header-logo.png)*/
+ /*background-image: url(./img/header-logo.png)*/
background-image: url(./img/svg/osm-logo_color_rgb.svg);
}
.login-cntnr .riftio {
--- /dev/null
+/*
+ *
+ * Copyright 2017 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import $ from 'jquery';
+
+const configPromise = new Promise((resolve, reject) => {
+ $.ajax({
+ url: '/app-config',
+ type: 'GET',
+ success: function (data) {
+ if (data.version.endsWith('.1')){
+ data.version = '' + Date.now();
+ }
+ resolve(data);
+ },
+ error: function (error) {
+ console.log("There was an error getting config: ", error);
+ reject(error);
+ }
+ }).fail(function (xhr) {
+ console.log('There was an xhr error getting the config', xhr);
+ reject(xhr);
+ });
+});
+
+module.exports = {
+ get: () => configPromise
+};
\ No newline at end of file
--- /dev/null
+var c = {};
+
+c.PLATFORM = {
+ OPER: "rw-rbac-platform:platform-oper",
+ ADMIN: "rw-rbac-platform:platform-admin",
+ SUPER: "rw-rbac-platform:super-admin"
+}
+
+c.PROJECT = {
+ TYPE: {
+ "rw-project-mano:catalog-oper": "rw-project-mano",
+ "rw-project-mano:catalog-admin": "rw-project-mano",
+ "rw-project-mano:lcm-oper": "rw-project-mano",
+ "rw-project-mano:lcm-admin": "rw-project-mano",
+ "rw-project-mano:account-oper": "rw-project-mano",
+ "rw-project-mano:account-admin": "rw-project-mano",
+ "rw-project:project-oper": "rw-project",
+ "rw-project:project-admin": "rw-project"
+ },
+ CATALOG_OPER: "rw-project-mano:catalog-oper",
+ CATALOG_ADMIN: "rw-project-mano:catalog-admin",
+ LCM_OPER: "rw-project-mano:lcm-oper",
+ LCM_ADMIN: "rw-project-mano:lcm-admin",
+ ACCOUNT_OPER: "rw-project-mano:account-oper",
+ ACCOUNT_ADMIN: "rw-project-mano:account-admin",
+ PROJECT_OPER: "rw-project:project-oper",
+ PROJECT_ADMIN: "rw-project:project-admin"
+
+}
+
+module.exports = c;
* limitations under the License.
*
*/
-//Login needs to be refactored. Too many cross dependencies
-var AuthActions = require('../widgets/login/loginAuthActions.js');
-var $ = require('jquery');
-import rw from './rw.js';
+import AuthActions from '../widgets/login/loginAuthActions';
+import $ from 'jquery';
+import rw from './rw';
+import appConfiguration from './appConfiguration'
+import SockJS from 'sockjs-client';
+
var API_SERVER = rw.getSearchParams(window.location).api_server;
let NODE_PORT = rw.getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
-var SockJS = require('sockjs-client');
var Utils = {};
var INACTIVITY_TIMEOUT = 600000;
-Utils.getInactivityTimeout = function() {
- return new Promise(function(resolve, reject) {
- $.ajax({
- url: '/inactivity-timeout',
- type: 'GET',
- success: function(data) {
- resolve(data);
- },
- error: function(error) {
- console.log("There was an error getting the inactivity-timeout: ", error);
- reject(error);
- }
- }).fail(function(xhr) {
- console.log('There was an xhr error getting the inactivity-timeout', xhr);
- reject(xhr);
- });
- });
-};
-
Utils.isMultiplexerLoaded = function() {
if (window.multiplexer) {
return true;
loadChecker();
};
-Utils.checkAndResolveSocketRequest = function(data, resolve, reject) {
+Utils.checkAndResolveSocketRequest = function(data, resolve, reject, successCallback) {
const checker = () => {
if (!Utils.isMultiplexerLoaded()) {
setTimeout(() => {
checker();
}, 500);
} else {
- resolve(data.id);
+ if (!successCallback) {
+ resolve(data.id);
+ } else {
+ //resolve handled in callback
+ successCallback(data.id)
+ }
}
};
};
Utils.bootstrapApplication = function() {
- var self = this;
- return new Promise(function(resolve, reject) {
- Promise.all([self.getInactivityTimeout()]).then(function(results) {
+ return new Promise((resolve, reject) => {
+ Promise.all([appConfiguration.get()]).then(function(results) {
INACTIVITY_TIMEOUT = results[0]['inactivity-timeout'];
resolve();
}, function(error) {
}
Utils.addAuthorizationStub = function(xhr) {
- var Auth = window.sessionStorage.getItem("auth");
- xhr.setRequestHeader('Authorization', 'Basic ' + Auth);
+ // NO-OP now that we are dealing with it on the server
+ // var Auth = window.sessionStorage.getItem("auth");
+ // xhr.setRequestHeader('Authorization', 'Basic ' + Auth);
};
Utils.getByteDataWithUnitPrefix = function(number, precision) {
}
}
Utils.loginHash = "#/login";
-Utils.setAuthentication = function(username, password, cb) {
- var self = this;
- var AuthBase64 = btoa(username + ":" + password);
- window.sessionStorage.setItem("auth", AuthBase64);
- self.detectInactivity();
- $.ajax({
- url: '//' + window.location.hostname + ':' + window.location.port + '/check-auth?api_server=' + API_SERVER,
- type: 'GET',
- beforeSend: Utils.addAuthorizationStub,
- success: function(data) {
- //console.log("LoggingSource.getLoggingConfig success call. data=", data);
- if (cb) {
- cb();
- };
- },
- error: function(data) {
- Utils.clearAuthentication();
- }
- });
-}
-Utils.clearAuthentication = function(callback) {
+
+Utils.clearAuthentication = function() {
var self = this;
window.sessionStorage.removeItem("auth");
AuthActions.notAuthenticated();
window.sessionStorage.setItem("locationRefHash", window.location.hash);
- if (callback) {
- callback();
- } else {
- window.location.hash = Utils.loginHash;
- }
+ var reloadURL = '';
+ $.ajax({
+ url: '//' + window.location.hostname + ':' + window.location.port + '/session?api_server=' + API_SERVER + '&hash=' + encodeURIComponent(window.location.hash),
+ type: 'DELETE',
+ success: function(data) {
+ console.log('User logged out');
+ reloadURL = data['url'] + '?post_logout_redirect_uri=' +
+ window.location.protocol + '//' +
+ window.location.hostname + ':' +
+ window.location.port +
+ '/?api_server=' + API_SERVER;
+
+ window.location.replace(reloadURL);
+ },
+ error: function(data) {
+ console.log('Problem logging user out');
+ }
+ });
}
Utils.isNotAuthenticated = function(windowLocation, callback) {
var self = this;
return displayMsg
}
+Utils.rpcError = (rpcResult) => {
+ try {
+ let info = JSON.parse(rpcResult);
+ let rpcError = info.body || info.errorMessage.body || info.errorMessage.error;
+ if (rpcError) {
+ if (typeof rpcError === 'string') {
+ const index = rpcError.indexOf('{');
+ if (index >= 0) {
+ return JSON.parse(rpcError.substr(index));
+ }
+ } else {
+ return rpcError;
+ }
+ }
+ } catch (e) {
+ }
+ console.log('invalid rpc error: ', rpcResult);
+ return null;
+}
+
module.exports = Utils;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
############################################################################ */
.SqButton {
- align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
border-style: solid;
border-radius: 3px;
border-width: 0px;
cursor: pointer;
+ display: -ms-inline-flexbox;
display: inline-flex;
font-size: 1rem;
height: 50px;
- justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
margin: 0 10px;
outline: none;
padding: 0 15px;
/* Focus */
&:focus {
- // box-shadow: $focus-shadow;
- border: 1px solid red;
+ /* box-shadow: $focus-shadow;*/
+ border: 1px solid;
+ border-color: darken($normalHoverBackground, 10%);
}
/* SIZES
fill: $primaryForeground;
}
}
-
-
}
-
+.sqButtonGroup {
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
Class += " is-disabled";
}
return (
- <div style={{display: 'flex'}}>
+ <div style={{display: 'flex'}} onClick={this.props.onClick}>
<div className={Class} tabIndex="0">
- {svgHTML}
- <div className="SqButton-content">{label}</div>
+ {svgHTML}
+ <div className="SqButton-content">{label}</div>
</div>
+ </div>
+ )
+ }
+}
+
+export class ButtonGroup extends React.Component {
+ render() {
+ let className = "sqButtonGroup";
+ if (this.props.className) {
+ className = `${className} ${this.props.className}`
+ }
+ return (
+ <div className={className} style={this.props.style}>
+ {this.props.children}
</div>
)
}
}
+
SqButton.defaultProps = {
+ onClick: function(e) {
+ console.log('Clicked')
+ },
icon: false,
primary: false,
disabled: false,
// Histogram: Histogram,
Multicomponent: require('./multicomponent/multicomponent.js'),
Mixins: require('./mixins/ButtonEventListener.js'),
- // Gauge: require('./gauge/gauge.js'),
+// Gauge: require('./gauge/gauge.js'),
Bullet: require('./bullet/bullet.js')
};
-// require('../../assets/js/n3-line-chart.js');
-// var Gauge = require('../../assets/js/gauge-modified.js');
-// var bulletController = function($scope, $element) {
-// this.$element = $element;
-// this.vertical = false;
-// this.value = 0;
-// this.min = 0;
-// this.max = 100;
-// //this.range = this.max - this.min;
-// //this.percent = (this.value - this.min) / this.range;
-// this.displayValue = this.value;
-// this.isPercent = (this.units == '')? true:false;
-// this.bulletColor = "#6BB814";
-// this.fontsize = 28;
-// this.radius = 4;
-// this.containerMarginX = 0;
-// this.containerMarginY = 0;
-// this.textMarginX = 5;
-// this.textMarginY = 42;
-// this.bulletMargin = 0;
-// this.width = 512;
-// this.height = 64;
-// this.markerX = -100; // puts it off screen unless set
-// var self = this;
-// if (this.isPercent) {
-// this.displayValue + "%";
-// }
-// $scope.$watch(
-// function() {
-// return self.value;
-// },
-// function() {
-// self.valueChanged();
-// }
-// );
-
-// }
-
-// bulletController.prototype = {
-
-// valueChanged: function() {
-// var range = this.max - this.min;
-// var normalizedValue = (this.value - this.min) / range;
-// if (this.isPercent) {
-// this.displayValue = String(Math.round(normalizedValue * 100)) + "%";
-// } else {
-// this.displayValue = this.value;
-// }
-// // All versions of IE as of Jan 2015 does not support inline CSS transforms on SVG
-// if (platform.name == 'IE') {
-// this.bulletWidth = Math.round(100 * normalizedValue) + '%';
-// } else {
-// this.bulletWidth = this.width - (2 * this.containerMarginX);
-// var transform = 'scaleX(' + normalizedValue + ')';
-// var bullet = $(this.$element).find('.bullet2');
-// bullet.css('transform', transform);
-// bullet.css('-webkit-transform', transform);
-// }
-// },
-
-// markerChanged: function() {
-// var range = this.max - this.min;
-// var w = this.width - (2 * this.containerMarginX);
-// this.markerX = this.containerMarginX + ((this.marker - this.min) / range ) * w;
-// this.markerY1 = 7;
-// this.markerY2 = this.width - 7;
-// }
-// }
-
-// angular.module('components', ['n3-line-chart'])
-// .directive('rwBullet', function() {
-// return {
-// restrict : 'E',
-// templateUrl: 'modules/views/rw.bullet.tmpl.html',
-// bindToController: true,
-// controllerAs: 'bullet',
-// controller: bulletController,
-// replace: true,
-// scope: {
-// min : '@?',
-// max : '@?',
-// value : '@',
-// marker: '@?',
-// units: '@?',
-// bulletColor: '@?',
-// label: '@?'
-// }
-// };
-// })
-// .directive('rwSlider', function() {
-// var controller = function($scope, $element, $timeout) {
-// // Q: is there a way to force attributes to be ints?
-// $scope.min = $scope.min || "0";
-// $scope.max = $scope.max || "100";
-// $scope.step = $scope.step || "1";
-// $scope.height = $scope.height || "30";
-// $scope.orientation = $scope.orientation || 'horizontal';
-// $scope.tooltipInvert = $scope.tooltipInvert || false;
-// $scope.percent = $scope.percent || false;
-// $scope.kvalue = $scope.kvalue || false;
-// $scope.direction = $scope.direction || "ltr";
-// $($element).noUiSlider({
-// start: parseInt($scope.value),
-// step: parseInt($scope.step),
-// orientation: $scope.orientation,
-// range: {
-// min: parseInt($scope.min),
-// max: parseInt($scope.max)
-// },
-// direction: $scope.direction
-// });
-// //$(".no-Ui-target").Link('upper').to('-inline-<div class="tooltip"></div>')
-// var onSlide = function(e, value) {
-// $timeout(function(){
-// $scope.value = value;
-// })
-
-// };
-// $($element).on({
-// change: onSlide,
-// slide: onSlide,
-// set: $scope.onSet({value: $scope.value})
-// });
-// var val = String(Math.round($scope.value));
-// if ($scope.percent) {
-// val += "%"
-// } else if ($scope.kvalue) {
-// val += "k"
-// }
-// $($element).height($scope.height);
-// if ($scope.tooltipInvert) {
-// $($element).find('.noUi-handle').append("<div class='tooltip' style='position:relative;right:20px'>" + val + "</div>");
-// } else {
-// $($element).find('.noUi-handle').append("<div class='tooltip' style='position:relative;left:-20px'>" + val + "</div>");
-// }
-// $scope.$watch('value', function(value) {
-// var val = String(Math.round($scope.value));
-// if ($scope.percent) {
-// val += "%"
-// } else if($scope.kvalue) {
-// val += "k"
-// }
-// $($element).val(value);
-// $($element).find('.tooltip').html(val);
-// if ($scope.tooltipInvert) {
-// $($element).find('.tooltip').css('right', $($element).find('.tooltip').innerWidth() * -1);
-// } else {
-// $($element).find('.tooltip').css('left', $($element).find('.tooltip').innerWidth() * -1);
-// }
-// });
-// };
-
-// return {
-// restrict : 'E',
-// template: '<div></div>',
-// controller : controller,
-// replace: true,
-// scope: {
-// min : '@',
-// max : '@',
-// width: '@',
-// height: '@',
-// step : '@',
-// orientation : '@',
-// tooltipInvert: '@',
-// percent: '@',
-// kvalue: '@?',
-// onSet:'&?',
-// direction: '@?',
-// value:'=?'
-// }
-// };
-// })
-// .directive('rwGauge', function() {
-// return {
-// restrict: 'AE',
-// template: '<canvas class="rwgauge" style="width:100%;height:100%;max-width:{{width}}px;max-height:240px;"></canvas>',
-// replace: true,
-// scope: {
-// min: '@?',
-// max: '@?',
-// size: '@?',
-// color: '@?',
-// value: '@?',
-// resize: '@?',
-// isAggregate: '@?',
-// units: '@?',
-// valueFormat: '=?',
-// width: '@?'
-// },
-// bindToController: true,
-// controllerAs: 'gauge',
-// controller: function($scope, $element) {
-// var self = this;
-// this.gauge = null;
-// this.min = this.min || 0;
-// this.max = this.max || 100;
-// this.nSteps = 14;
-// this.size = this.size || 300;
-// this.units = this.units || '';
-// $scope.width = this.width || 240;
-// this.color = this.color || 'hsla(212, 57%, 50%, 1)';
-// if (!this.valueFormat) {
-// if (this.max > 1000 || this.value) {
-// self.valueFormat = {
-// "int": 1,
-// "dec": 0
-// };
-// } else {
-// self.valueFormat = {
-// "int": 1,
-// "dec": 2
-// };
-// }
-// }
-// this.isAggregate = this.isAggregate || false;
-// this.resize = this.resize || false;
-// if (this.format == 'percent') {
-// self.valueFormat = {
-// "int": 3,
-// "dec": 0
-// };
-// }
-// $scope.$watch(function() {
-// return self.max;
-// }, function(n, o) {
-// if(n !== o) {
-// renderGauge();
-// }
-// });
-// $scope.$watch(function() {
-// return self.valueFormat;
-// }, function(n, o) {
-// if(n != 0) {
-// renderGauge();
-// }
-// });
-// $scope.$watch(function() {
-// return self.value;
-// }, function() {
-// if (self.gauge) {
-// // w/o rounding gauge will unexplainably thrash round.
-// self.valueFormat = determineValueFormat(self.value);
-// self.gauge.setValue(Math.ceil(self.value * 100) / 100);
-// //self.gauge.setValue(Math.round(self.value));
-// }
-// });
-// angular.element($element).ready(function() {
-// console.log('rendering')
-// renderGauge();
-// })
-// window.testme = renderGauge;
-// function determineValueFormat(value) {
-
-// if (value > 999 || self.units == "%") {
-// return {
-// "int": 1,
-// "dec": 0
-// }
-// }
-
-// return {
-// "int": 1,
-// "dec": 2
-// }
-// }
-// function renderGauge(calcWidth) {
-// if (self.max == self.min) {
-// self.max = 14;
-// }
-// var range = self.max - self.min;
-// var step = Math.round(range / self.nSteps);
-// var majorTicks = [];
-// for (var i = 0; i <= self.nSteps; i++) {
-// majorTicks.push(self.min + (i * step));
-// };
-// var redLine = self.min + (range * 0.9);
-// var config = {
-// isAggregate: self.isAggregate,
-// renderTo: angular.element($element)[0],
-// width: calcWidth || self.size,
-// height: calcWidth || self.size,
-// glow: false,
-// units: self.units,
-// title: false,
-// minValue: self.min,
-// maxValue: self.max,
-// majorTicks: majorTicks,
-// valueFormat: determineValueFormat(self.value),
-// minorTicks: 0,
-// strokeTicks: false,
-// highlights: [],
-// colors: {
-// plate: 'rgba(0,0,0,0)',
-// majorTicks: 'rgba(15, 123, 182, .84)',
-// minorTicks: '#ccc',
-// title: 'rgba(50,50,50,100)',
-// units: 'rgba(50,50,50,100)',
-// numbers: '#fff',
-// needle: {
-// start: 'rgba(255, 255, 255, 1)',
-// end: 'rgba(255, 255, 255, 1)'
-// }
-// }
-// };
-// var min = config.minValue;
-// var max = config.maxValue;
-// var N = 1000;
-// var increment = (max - min) / N;
-// for (i = 0; i < N; i++) {
-// var temp_color = 'rgb(0, 172, 238)';
-// if (i > 0.5714 * N && i <= 0.6428 * N) {
-// temp_color = 'rgb(0,157,217)';
-// } else if (i >= 0.6428 * N && i < 0.7142 * N) {
-// temp_color = 'rgb(0,142,196)';
-// } else if (i >= 0.7142 * N && i < 0.7857 * N) {
-// temp_color = 'rgb(0,126,175)';
-// } else if (i >= 0.7857 * N && i < 0.8571 * N) {
-// temp_color = 'rgb(0,122,154)';
-// } else if (i >= 0.8571 * N && i < 0.9285 * N) {
-// temp_color = 'rgb(0,96,133)';
-// } else if (i >= 0.9285 * N) {
-// temp_color = 'rgb(0,80,112)';
-// }
-// config.highlights.push({
-// from: i * increment,
-// to: increment * (i + 2),
-// color: temp_color
-// })
-// }
-// var updateSize = _.debounce(function() {
-// config.maxValue = self.max;
-// var clientWidth = self.parentNode.parentNode.clientWidth / 2;
-// var calcWidth = (300 > clientWidth) ? clientWidth : 300;
-// self.gauge.config.width = self.gauge.config.height = calcWidth;
-// self.renderGauge(calcWidth);
-// }, 500);
-// if (self.resize) $(window).resize(updateSize)
-// if (self.gauge) {
-// self.gauge.updateConfig(config);
-// } else {
-// self.gauge = new Gauge(config);
-// self.gauge.draw();
-// }
-// };
-// },
-// }
-// });
--- /dev/null
+import './formControls.jsx';
+
+import React from 'react'
+import SelectOption from 'widgets/form_controls/selectOption.jsx';
+import imgAdd from '../../../node_modules/open-iconic/svg/plus.svg'
+import imgRemove from '../../../node_modules/open-iconic/svg/trash.svg'
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import Input from 'widgets/form_controls/input.jsx';
+
+export class FormSection extends React.Component {
+ render() {
+ let className = 'FormSection ' + this.props.className;
+ let html = (
+ <div
+ style={this.props.style}
+ className={className}
+ >
+ <div className="FormSection-title">
+ {this.props.title}
+ </div>
+ <div className="FormSection-body">
+ {this.props.children}
+ </div>
+ </div>
+ );
+ return html;
+ }
+}
+
+FormSection.defaultProps = {
+ className: ''
+}
+
+/**
+ * AddItemFn:
+ */
+export class InputCollection extends React.Component {
+ constructor(props) {
+ super(props);
+ this.collection = props.collection;
+ }
+ buildTextInput(onChange, v, i) {
+ return (
+ <Input
+ readonly={this.props.readonly}
+ style={{flex: '1 1'}}
+ key={i}
+ value={v}
+ onChange= {onChange.bind(null, i)}
+ />
+ )
+ }
+ buildSelectOption(initial, options, onChange, v, i) {
+ return (
+ <SelectOption
+ readonly={this.props.readonly}
+ key={`${i}-${v.replace(' ', '_')}`}
+ intial={initial}
+ defaultValue={v}
+ options={options}
+ onChange={onChange.bind(null, i)}
+ />
+ );
+ }
+ showInput() {
+
+ }
+ render() {
+ const props = this.props;
+ let inputType;
+ let className = "InputCollection";
+ if (props.className) {
+ className = `${className} ${props.className}`;
+ }
+ if (props.type == 'select') {
+ inputType = this.buildSelectOption.bind(this, props.initial, props.options, props.onChange);
+ } else {
+ inputType = this.buildTextInput.bind(this, props.onChange)
+ }
+ let html = (
+ <div className="InputCollection-wrapper">
+ {props.collection.map((v,i) => {
+ return (
+ <div key={i} className={className} >
+ {inputType(v, i)}
+ {
+ props.readonly ? null : <span onClick={props.RemoveItemFn.bind(null, i)} className="removeInput"><img src={imgRemove} />Remove</span>}
+ </div>
+ )
+ })}
+ { props.readonly ? null : <span onClick={props.AddItemFn} className="addInput"><img src={imgAdd} />Add</span>}
+ </div>
+ );
+ return html;
+ }
+}
+
+InputCollection.defaultProps = {
+ input: Input,
+ collection: [],
+ onChange: function(i, e) {
+ console.log(`
+ Updating with: ${e.target.value}
+ At index of: ${i}
+ `)
+ },
+ AddItemFn: function(e) {
+ console.log(`Adding a new item to collection`)
+ },
+ RemoveItemFn: function(i, e) {
+ console.log(`Removing item from collection at index of: ${i}`)
+ }
+}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* limitations under the License.
*
*/
-@import 'style/_colors.scss';
+@import '../../style/_colors.scss';
.sqTextInput {
display: -ms-flexbox;
color:$darker-gray;
text-transform:uppercase;
}
- input, .readonly, textarea {
+ input, textarea {
height: 35px;
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+ /* box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;*/
font-size: 1rem;
display: block;
background: white !important;
.readonly {
line-height: 35px;
box-shadow:none;
+ background:none !important;
}
textarea {
-ms-flex-align: stretch;
border:0px;
height: 100%;
}
+ &.checkbox {
+ -ms-flex-direction:row;
+ flex-direction:row;
+ -ms-flex-align:center;
+ align-items:center;
+ margin-bottom:0;
+ >span {
+ -ms-flex-order: 1;
+ order: 1;
+ padding-left:1rem;
+ }
+ >input {
+ -ms-flex-order: 0;
+ order: 0;
+
+ box-shadow:none;
+ height:25px;
+ }
+ }
+ .invalid {
+ color: red;
+ font-weight:strong;
+ }
+ input:invalid {
+ border: 2px solid red;
+ &:after {
+ content: 'Invalid Value'
+ }
+ }
+}
+
+.sqCheckBox {
+ display:-ms-flexbox;
+ display:flex;
+ label {
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex-align: center;
+ align-items: center;
+ input {
+ box-shadow: none;
+ height: auto;
+ margin: 0 0.25rem;
+ }
+ }
+}
+
+.FormSection {
+ &-title {
+ color: #000;
+ background: lightgray;
+ padding: 0.5rem;
+ border-top: 1px solid #f1f1f1;
+ border-bottom: 1px solid #f1f1f1;
+ }
+ &-body {
+ padding: 0.5rem 0.75rem;
+ }
+ label {
+ -ms-flex: 1 0;
+ flex: 1 0;
+ }
+ /* label {*/
+ /* display: -ms-flexbox;*/
+ /* display: flex;*/
+ /* -ms-flex-direction: column;*/
+ /* flex-direction: column;*/
+ /* width: 100%;*/
+ /* margin: 0.5rem 0;*/
+ /* -ms-flex-align: start;*/
+ /* align-items: flex-start;*/
+ /* -ms-flex-pack: start;*/
+ /* justify-content: flex-start;*/
+ /* }*/
+ select {
+ font-size: 1rem;
+ min-width: 75%;
+ height: 35px;
+ }
+}
+
+
+
+
+.InputCollection {
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -ms-flex-align: center;
+ align-items: center;
+ button {
+ padding: 0.25rem;
+ height: 1.5rem;
+ font-size: 0.75rem;
+ }
+ select {
+ min-width: 100%;
+ }
+ margin-bottom:0.5rem;
+ &-wrapper {
+
+ }
}
--- /dev/null
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import './formControls.scss';
+import SelectOption from 'widgets/form_controls/selectOption.jsx';
+import CheckSVG from '../../../node_modules/open-iconic/svg/check.svg'
+import React, {Component} from 'react';
+
+export default class Input extends Component {
+ render() {
+ let {label, value, defaultValue, ...props} = this.props;
+ let inputProperties = {
+ value: value
+ }
+ let isRequired;
+ let inputType;
+ let tester = null;
+ let className = `sqTextInput ${props.className}`;
+
+ if(this.props.required) {
+ isRequired = <span className="required">*</span>
+ }
+ if (defaultValue) {
+ inputProperties.defaultValue = defaultValue;
+ }
+ if (props.pattern) {
+ inputProperties.pattern = props.pattern;
+ tester = new RegExp(props.pattern);
+ }
+ if(props.hasOwnProperty('type') && (props.type.toLowerCase() == 'checkbox')) {
+ inputProperties.checked = props.checked;
+ className = `${className} checkbox`;
+ }
+ if (value == undefined) {
+ value = defaultValue;
+ }
+ switch(props.type) {
+ case 'textarea':
+ inputType = <textarea key={props.key} {...inputProperties} value={value} onChange={props.onChange} />
+ break;
+ case 'select':
+ inputType = <SelectOption
+ key={props.key}
+ initial={props.initial}
+ defaultValue={defaultValue}
+ options={props.options}
+ onChange={props.onChange}
+ />
+ break;
+ case 'radiogroup':
+ inputType = buildRadioButtons(this.props);
+ break;
+ default:
+ inputType = <input key={props.key} type={props.type} {...inputProperties} onChange={props.onChange} placeholder={props.placeholder}/>;
+ }
+ let displayedValue;
+ if(value === null) {
+ displayedValue = null;
+ } else {
+ displayedValue = value.toString();
+ }
+ if( props.readonly && props.type == "checkbox" && props.checked ) {
+ displayedValue = <img src={CheckSVG} />
+ }
+
+ if( props.readonly && props.type == "radiogroup" && props.readonlydisplay ) {
+ displayedValue = props.readonlydisplay
+ }
+
+ let html = (
+ <label className={className} style={props.style}>
+ <span> { label } {isRequired}</span>
+ {
+ !props.readonly ? inputType : <div className="readonly">{displayedValue}</div>
+ }
+ {
+ !props.readonly && tester && value && !tester.test(value) ? <span className="invalid">The Value you entered is invalid</span> : null
+ }
+ </label>
+ );
+ return html;
+ }
+}
+
+
+function buildRadioButtons(props) {
+ let className = 'sqCheckBox';
+ return(
+ <div className={className}>
+ {
+ props.options.map((o,i) => {
+ let label = o.label || o;
+ let value = o.value || o;
+ return (
+ <label key={i}>
+ {label}
+ <input type="radio" checked={props.value == value} value={value} onChange={props.onChange} />
+ </label>
+ )
+ })
+ }
+ </div>
+
+ )
+}
+
+Input.defaultProps = {
+ onChange: function(e) {
+ console.log(e.target.value, e);
+ console.dir(e.target);
+ },
+ label: '',
+ defaultValue: null,
+ type: 'text',
+ readonly: false,
+ style:{},
+ className: ''
+
+}
+
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
render() {
let html;
let defaultValue = this.props.defaultValue;
- let options = this.props.options.map(function(op, i) {
- let value = JSON.stringify(op.value);
- return <option key={i} value={JSON.stringify(op.value)}>{op.label}</option>
- });
+ let options = this.props.options && this.props.options.map(function(op, i) {
+ let value;
+ let label;
+ if(typeof(op) == 'object') {
+ value = JSON.stringify(op.value);
+ label = op.label;
+ } else {
+ value = op;
+ label = op;
+ }
+
+ 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>
- {this.props.label}
- <select className={this.props.className} onChange={this.handleOnChange} defaultValue={JSON.stringify(defaultValue)} >
- {
- options
- }
- </select>
+ <label key={this.props.key} className={this.props.className}>
+ <span>{this.props.label}</span>
+ {
+ this.props.readonly ? defaultValue
+ : (
+ <select
+ className={this.props.className}
+ onChange={this.handleOnChange}
+ value={JSON.stringify(this.props.value)}
+ defaultValue={JSON.stringify(defaultValue)}>
+ {
+ options
+ }
+ </select>
+ )
+ }
</label>
);
return html;
}
}
SelectOption.defaultProps = {
+ /**
+ * [options description]
+ * @type {Array} - Expects items to contain objects with the properties 'label' and 'value' which are both string types. Hint: JSON.stringify()
+ */
options: [],
onChange: function(e) {
+ console.log(e.target.value)
console.dir(e)
},
- defaultValue: false,
+ readonly: false,
+ /**
+ * Selected or default value
+
+ * @type {[type]}
+ */
+ defaultValue: null,
+ /**
+ * True if first entry in dropdown should be blank
+ * @type {Boolean}
+ */
initial: false,
label: null
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
import './formControls.scss';
import React, {Component} from 'react';
-
-export default class TextInput extends Component {
- render() {
- let {label, onChange, value, defaultValue, ...props} = this.props;
- let inputProperties = {
- value: value,
- onChange: onChange
- }
- let isRequired;
- let inputType;
- if(this.props.required) {
- isRequired = <span className="required">*</span>
- }
- if (defaultValue) {
- inputProperties.defaultValue = defaultValue;
- }
- if (props.pattern) {
- inputProperties.pattern = props.pattern;
- }
- if (value == undefined) {
- value = defaultValue;
- }
- switch(props.type) {
- case 'textarea':
- inputType = <textarea {...inputProperties} value={value}/>
-
- break;
- default:
- inputType = <input type={props.type} {...inputProperties} placeholder={props.placeholder}/>;
- }
- let html = (
- <label className={"sqTextInput " + props.className} style={props.style}>
- <span> { label } {isRequired}</span>
- {
- !props.readonly ? inputType : <div className="readonly">{value}</div>
- }
-
- </label>
- );
- return html;
+import Input from './input.jsx';
+class TextInput extends Input {
+ constructor(props) {
+ super(props);
+ console.warn('TextInput is deprecated. Use Input component instead')
}
}
-
-TextInput.defaultProps = {
- onChange: function(e) {
- console.log(e.target.value);
- },
- label: '',
- defaultValue: undefined,
- type: 'text',
- readonly: false,
- style:{}
-
-}
+export default TextInput;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
header.header-app-component {
- padding: 20px 0px;
+ padding: 10px 0px;
+ display:-ms-flexbox;
display:flex;
- flex-direction:column;
+ -ms-flex-direction:column;
+ flex-direction:column;
.header-app-main {
+ display:-ms-flexbox;
display:flex;
- flex-direction:row;
- justify-content:space-between;
- align-items:center;
+ -ms-flex-direction:row;
+ flex-direction:row;
+ -ms-flex-pack:justify;
+ justify-content:space-between;
+ -ms-flex-align:center;
+ align-items:center;
}
h1 {
/*background: url('../../style/img/header-logo.png') no-repeat;*/
font-size: 1.625rem;
font-weight: 400;
position:relative;
- flex: 1 0 auto;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
}
ul {
+ display:-ms-flexbox;
display:flex;
}
li {
+ display:-ms-flexbox;
display:flex;
- flex:1 1 auto;
+ -ms-flex:1 1 auto;
+ flex:1 1 auto;
border-right:1px solid #e5e5e5;
padding: 0 1rem;
&:last-child {
}
a {
cursor:pointer;
- // padding: 0.125rem;
- // border-bottom:1px solid black;
+ /* padding: 0.125rem;*/
+ /* border-bottom:1px solid black;*/
text-decoration:underline;
}
}
.header-app-nav {
+ display:-ms-flexbox;
display:flex;
margin-left: 0.25rem;
a,span {
}
}
nav {
+ display:-ms-flexbox;
display:flex;
- flex:0 1 auto;
- align-items:center;
+ -ms-flex:0 1 auto;
+ flex:0 1 auto;
+ -ms-flex-align:center;
+ align-items:center;
}
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
}
render() {
if(!this.props.hasFailed) {
- return (<span className='throttledMessageText'>{this.state.displayMessage}</span>)
+ return (<span className='throttledMessageText' style={{margin:'1rem'}}>{this.state.displayMessage}</span>)
} else {
return (<span> </span>)
}
import React, {Component} from 'react';
import 'style/core.css';
import './panel.scss';
+import circleXImage from '../../../node_modules/open-iconic/svg/circle-x.svg';
export class Panel extends Component {
constructor(props) {
super(props)
let classRoot = className ? ' ' + className : ' ';
let hasCorners = this.props['no-corners'];
let titleTag = title ? <header className="skyquakePanel-title">{title}</header> : '';
+ let closeButton = (
+ <a onClick={self.props.hasCloseButton}
+ className={"close-btn"}>
+ <img src={circleXImage} title="Close card" />
+ </a>
+ );
return (
<section className={'skyquakePanel' + classRoot} style={props.style}>
+ { self.props.hasCloseButton ? closeButton : null}
{ !hasCorners ? <i className="corner-accent top left"></i> : null }
{ !hasCorners ? <i className="corner-accent top right"></i> : null }
{titleTag}
export class PanelWrapper extends Component {
render() {
+ let wrapperClass = 'skyquakePanelWrapper';
+ let {className, column, style, ...props} = this.props;
+ if(className) {
+ wrapperClass = `${wrapperClass} ${className}`
+ }
+ if(column) {
+ style.flexDirection = 'column';
+ }
return (
- <div className={'skyquakePanelWrapper ' + this.props.className} style={this.props.style}>
+ <div className={wrapperClass} style={style} {...props}>
{this.props.children}
</div>)
}
}
-
+PanelWrapper.defaultProps = {
+ style: {}
+}
export default Panel;
width:100%;
height:100%;
}
+ .close-btn {
+ cursor:pointer;
+ position: absolute;
+ right: -0.5rem;
+ top: -0.5rem;
+ img {
+ width: 1rem;
+ }
+ }
}
.skyquakePanelWrapper.column {
+ -ms-flex-direction:column;
+ flex-direction:column;
+ display:-ms-flexbox;
+ display:flex;
.skyquakePanel-wrapper {
height:auto;
}
*
*/
- /**
- * EventCenter module to display a list of events from the system
- * @module framework/widgets/skyquake_container/EventCenter
- * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
- *
- */
+/**
+ * EventCenter module to display a list of events from the system
+ * @module framework/widgets/skyquake_container/EventCenter
+ * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
+ *
+ */
import React from 'react';
import { Link } from 'react-router';
import _isEqual from 'lodash/isEqual';
import _merge from 'lodash/merge';
import _indexOf from 'lodash/indexOf';
+import _isArray from 'lodash/isArray';
+import _sortBy from 'lodash/sortBy';
import '../../../node_modules/react-treeview/react-treeview.css';
import './eventCenter.scss';