Commit 965f03d7 by John Doe

updates for new interface API

parent 42a5ed30
...@@ -54,6 +54,10 @@ module Joule ...@@ -54,6 +54,10 @@ module Joule
@backend.module_interface(joule_module, req) @backend.module_interface(joule_module, req)
end end
def module_post_interface(joule_module, req)
@backend.module_post_interface(joule_module, req)
end
def node_type def node_type
'joule' 'joule'
end end
......
...@@ -71,6 +71,10 @@ module Joule ...@@ -71,6 +71,10 @@ module Joule
self.class.get("#{@url}/interface/#{joule_module.joule_id}/#{req}") self.class.get("#{@url}/interface/#{joule_module.joule_id}/#{req}")
end end
def module_post_interface(joule_module, req)
self.class.post("#{@url}/interface/#{joule_module.joule_id}/#{req}")
end
def stream_info(joule_id) def stream_info(joule_id)
begin begin
resp = self.class.get("#{@url}/stream.json?id=#{joule_id}") resp = self.class.get("#{@url}/stream.json?id=#{joule_id}")
...@@ -147,7 +151,23 @@ module Joule ...@@ -147,7 +151,23 @@ module Joule
return { error: true, msg: "error updating #{db_stream.path} metadata" } return { error: true, msg: "error updating #{db_stream.path} metadata" }
end end
{ error: false, msg: 'success' } { error: false, msg: 'success' }
end
def update_folder(db_folder)
attrs = { name: db_folder.name,
description: db_folder.description}.to_json
begin
response = self.class.put("#{@url}/folder.json",
body: {
id: db_folder.joule_id,
folder: attrs})
rescue
return { error: true, msg: 'cannot contact Joule server' }
end
unless response.success?
return { error: true, msg: "error updating #{db_folder.path} metadata" }
end
{ error: false, msg: 'success' }
end end
end end
end end
class InterfacePermissionsController < ApplicationController
before_action :authenticate_user!
before_action :set_nilm
before_action :authorize_admin
# GET /interface/:id/permissions.json
def index
# return permissions for nilm specified by nilm_id
@permissions = @nilm.permissions.includes(:user, :user_group)
end
# POST /permissions
# POST /permissions.json
def create
# create permission for nilm specified by nilm_id
@service = CreatePermission.new
@service.run(@nilm, params[:role], params[:target], params[:target_id])
@permission = @service.permission
render status: @service.success? ? :ok : :unprocessable_entity
end
# DELETE /permissions/1
# DELETE /permissions/1.json
def destroy
# remove permission from nilm specified by nilm_id
@service = DestroyPermission.new
@service.run(@nilm, current_user, params[:id])
render status: @service.success? ? :ok : :unprocessable_entity
end
# PUT /permissions/create_user.json
def create_user
@service = StubService.new
user = User.new(user_params)
unless user.save
@service.errors = user.errors.full_messages
render 'helpers/empty_response', status: :unprocessable_entity
return
end
@service = CreatePermission.new
@service.run(@nilm, params[:role], 'user', user.id)
@permission = @service.permission
@service.add_notice('created user')
render :create, status: @service.success? ? :ok : :unprocessable_entity
end
# PUT /permissions/invite_user.json
def invite_user
invitation_service = InviteUser.new()
invitation_service.run(
current_user,
params[:email],
params[:redirect_url])
unless invitation_service.success?
@service = invitation_service
render 'helpers/empty_response', status: :unprocessable_entity
return
end
@service = CreatePermission.new
@service.absorb_status(invitation_service)
@service.run(@nilm, params[:role], 'user', invitation_service.user.id)
@permission = @service.permission
render :create, status: @service.success? ? :ok : :unprocessable_entity
end
private
def set_nilm
@nilm = Nilm.find_by_id(params[:nilm_id])
head :not_found unless @nilm
end
def user_params
params.permit(:first_name, :last_name, :email,
:password, :password_confirmation)
end
# authorization based on nilms
def authorize_admin
head :unauthorized unless current_user.admins_nilm?(@nilm)
end
end
...@@ -5,6 +5,14 @@ class InterfacesController < ActionController::Base ...@@ -5,6 +5,14 @@ class InterfacesController < ActionController::Base
after_action :allow_wattsworth_iframe after_action :allow_wattsworth_iframe
#GET /authenticate #GET /authenticate
def authenticate def authenticate
#if the user is already authenticated just destroy the token and redirect
if _authenticate_interface_user
token = InterfaceAuthToken.find_by_value(params[:token])
token.destroy unless token.nil?
redirect_to Rails.configuration.interface_url_template.call(@joule_module.id)
return
end
# otherwise log them in
reset_session reset_session
token = InterfaceAuthToken.find_by_value(params[:token]) token = InterfaceAuthToken.find_by_value(params[:token])
render :unauthorized and return if token.nil? render :unauthorized and return if token.nil?
...@@ -12,26 +20,37 @@ class InterfacesController < ActionController::Base ...@@ -12,26 +20,37 @@ class InterfacesController < ActionController::Base
token.destroy token.destroy
session[:user_id]=token.user.id session[:user_id]=token.user.id
session[:interface_id]=token.joule_module.id session[:interface_id]=token.joule_module.id
redirect_to '/' redirect_to Rails.configuration.interface_url_template.call(token.joule_module.id)
end end
#GET /logout #GET /logout
def logout def logout
reset_session reset_session
redirect_to '/' redirect_to Rails.configuration.interface_url_template.call(token.joule_module.id)
end end
#everything else is proxied #everything else is proxied
def get def get
path = params[:path] || '' path = request.fullpath.sub("/interfaces/#{@joule_module.id}", "")
req = path +"?"+request.query_string proxied_response = @node_adapter.module_interface(@joule_module,path)
render plain: @node_adapter.module_interface(@joule_module,req)
render plain: proxied_response.body
proxied_response.headers.each do |key,value|
response.headers[key] = value
end
end end
def put def put
end end
def post def post
path = request.fullpath.sub("/interfaces/#{@joule_module.id}", "")
proxied_response = @node_adapter.module_post_interface(@joule_module,path)
render plain: proxied_response.body
proxied_response.headers.each do |key,value|
response.headers[key] = value
end
end end
def delete def delete
...@@ -40,18 +59,27 @@ class InterfacesController < ActionController::Base ...@@ -40,18 +59,27 @@ class InterfacesController < ActionController::Base
private private
def authenticate_interface_user! def authenticate_interface_user!
@current_user = User.find_by_id(session[:user_id]) render :unauthorized unless _authenticate_interface_user
@joule_module = JouleModule.find_by_id(session[:interface_id])
render :unauthorized if (@current_user.nil? || @joule_module.nil?)
#verify the session matches the URL #verify the session matches the URL
#verify the user has permissions on this module #verify the user has permissions on this module
end end
def _authenticate_interface_user
@current_user = User.find_by_id(session[:user_id])
@joule_module = JouleModule.find_by_id(session[:interface_id])
if @current_user.nil? || @joule_module.nil?
return false
end
#@role = @current_user.module_role(@joule_module)
#return false if @role.nil?
true
end
def allow_wattsworth_iframe def allow_wattsworth_iframe
urls = Rails.application.config_for(:urls) urls = Rails.application.config_for(:urls)
# TODO: check if this does anything... # TODO: check if this does anything...
response.headers['X-Frame-Options'] = "ALLOW-FROM #{urls['frontend']}" response.headers['X-Frame-Options'] = "" #ALLOW-FROM #{urls['frontend']}"
end end
def create_adapter def create_adapter
......
...@@ -7,7 +7,7 @@ class JouleModulesController < ApplicationController ...@@ -7,7 +7,7 @@ class JouleModulesController < ApplicationController
@nilm = @joule_module.nilm @nilm = @joule_module.nilm
head :unauthorized and return unless current_user.views_nilm?(@nilm) head :unauthorized and return unless current_user.views_nilm?(@nilm)
if(@joule_module.web_interface) if @joule_module.web_interface
token = InterfaceAuthToken.create(joule_module: @joule_module, token = InterfaceAuthToken.create(joule_module: @joule_module,
user: current_user, expiration: 5.minutes.from_now) user: current_user, expiration: 5.minutes.from_now)
@module_url = _interface_authentication_url(token) @module_url = _interface_authentication_url(token)
...@@ -18,10 +18,10 @@ class JouleModulesController < ApplicationController ...@@ -18,10 +18,10 @@ class JouleModulesController < ApplicationController
private private
def _interface_authentication_url(token) def _interface_authentication_url(token)
urls = Rails.application.config_for(:urls) #urls = Rails.application.config_for(:urls)
#eg: http://3.interfaces.wattsworth.net/authenticate?token=1234 #eg: http://3.interfaces.wattsworth.net/authenticate?token=1234
urls["interfaces"].gsub("XX",token.joule_module.id.to_s)+ Rails.configuration.interface_url_template.call(
"/authenticate?token="+token.value token.joule_module.id)+"/authenticate?token="+token.value
end end
end end
class InterfacePermission < ApplicationRecord
#---Associations----
belongs_to :user
belongs_to :user_group
belongs_to :joule_module
#---Validations---
validate :user_xor_group
def user_xor_group
unless user.blank? ^ user_group.blank?
errors.add(:base, "specify a user or group not both")
end
end
def target_name
if self.user_id?
if self.user.name.empty?
return self.user.email
else
return self.user.name
end
elsif self.user_group_id?
return self.user_group.name
else
return "[no target set]"
end
end
def target_type
if self.user_id?
return 'user'
elsif self.user_group_id?
return 'group'
else
return 'unknown'
end
end
def self.json_keys
[:id, :joule_module_id, :role, :priority]
end
end
...@@ -15,7 +15,7 @@ json.data do ...@@ -15,7 +15,7 @@ json.data do
end end
json.jouleModules(@nilm.joule_modules) do |m| json.jouleModules(@nilm.joule_modules) do |m|
json.extract! m, *JouleModule.json_keys json.extract! m, *JouleModule.json_keys
json.url Rails.configuration.interface_url_template.call(m.joule_id) json.url Rails.configuration.interface_url_template.call(m.id)
json.nilm_id @nilm.id json.nilm_id @nilm.id
end end
end end
......
...@@ -67,7 +67,8 @@ Rails.application.configure do ...@@ -67,7 +67,8 @@ Rails.application.configure do
end end
end end
config.interface_url_template = lambda do |id| config.interface_url_template = lambda do |id|
return "http://#{id}.interfaces.wattsworth.local" #return "http://#{id}.interfaces.wattsworth.local"
return "http://wattsworth.local/api/interfaces/#{id}"
end end
end end
...@@ -51,4 +51,5 @@ Rails.application.routes.draw do ...@@ -51,4 +51,5 @@ Rails.application.routes.draw do
get 'interfaces/:id/authenticate', to: 'interfaces#authenticate' get 'interfaces/:id/authenticate', to: 'interfaces#authenticate'
get 'interfaces/:id', to: 'interfaces#get' get 'interfaces/:id', to: 'interfaces#get'
get 'interfaces/:id/*path', to: 'interfaces#get' get 'interfaces/:id/*path', to: 'interfaces#get'
post 'interfaces/:id/*path', to: 'interfaces#post'
end end
class AddInterfacePermissions < ActiveRecord::Migration[5.2]
def change
create_table "interface_permissions", :force => true do |t|
t.integer "interface_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
t.integer "user_group_id"
t.string "role"
t.integer "precedence"
t.index :interface_id
end
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2018_08_07_001215) do ActiveRecord::Schema.define(version: 2018_08_18_012410) do
create_table "data_views", force: :cascade do |t| create_table "data_views", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
...@@ -121,6 +121,17 @@ ActiveRecord::Schema.define(version: 2018_08_07_001215) do ...@@ -121,6 +121,17 @@ ActiveRecord::Schema.define(version: 2018_08_07_001215) do
t.index ["user_id"], name: "index_interface_auth_tokens_on_user_id" t.index ["user_id"], name: "index_interface_auth_tokens_on_user_id"
end end
create_table "interface_permissions", force: :cascade do |t|
t.integer "interface_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "user_group_id"
t.string "role"
t.integer "precedence"
t.index ["interface_id"], name: "index_interface_permissions_on_interface_id"
end
create_table "joule_modules", force: :cascade do |t| create_table "joule_modules", force: :cascade do |t|
t.string "name" t.string "name"
t.string "description" t.string "description"
......
require 'rails_helper'
RSpec.describe InterfacePermissionsController, type: :controller do
end
FactoryBot.define do
factory :interface_permission do
end
end
require 'rails_helper'
RSpec.describe InterfacePermission, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment