From cbea42aab6b87905935e28bb2b30184eceef846d Mon Sep 17 00:00:00 2001 From: Heiko Bernloehr Date: Wed, 18 Jun 2014 10:01:32 +0200 Subject: WIP: subparticipants. --- app/controllers/application_controller.rb | 17 +++ app/controllers/subparticipants_controller.rb | 127 +++++++++++++++++++++ app/helpers/subparticipants_helper.rb | 19 +++ app/models/identity.rb | 9 ++ app/models/participant.rb | 9 +- app/models/subparticipant.rb | 98 ++++++++++++++++ config/environments/development.rb | 4 +- config/routes.rb | 3 + .../20140525164346_create_subparticipants.rb | 32 ++++++ db/schema.rb | 10 +- test/fixtures/subparticipants.yml | 24 ++++ test/functional/subparticipants_controller_test.rb | 25 ++++ test/unit/helpers/subparticipants_helper_test.rb | 21 ++++ test/unit/subparticipant_test.rb | 42 +++++++ 14 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 app/controllers/subparticipants_controller.rb create mode 100644 app/helpers/subparticipants_helper.rb create mode 100644 app/models/subparticipant.rb create mode 100644 db/migrate/20140525164346_create_subparticipants.rb create mode 100644 test/fixtures/subparticipants.yml create mode 100644 test/functional/subparticipants_controller_test.rb create mode 100644 test/unit/helpers/subparticipants_helper_test.rb create mode 100644 test/unit/subparticipant_test.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 00cfc4b..109e951 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -132,6 +132,23 @@ protected Participant.touch_ttl(@participant) if @participant.anonymous end + def block_anonymous_participants + if @participant.anonymous + raise Ecs::AuthenticationException, "Anonymous participants not allowed." + end + end + + def block_subparticipants + if @participant.subparticipant + raise Ecs::AuthenticationException, "Subparticipants not allowed." + end + end + + def check_json_contenttype + unless Mime::Type.lookup(request.headers["CONTENT_TYPE"]) =~ "application/json" + raise Ecs::InvalidMimetypeException, "Please provide \"Content-Type: application/json\" header for json data." + end unless request.raw_post.empty? + end # error pages diff --git a/app/controllers/subparticipants_controller.rb b/app/controllers/subparticipants_controller.rb new file mode 100644 index 0000000..4d1b3af --- /dev/null +++ b/app/controllers/subparticipants_controller.rb @@ -0,0 +1,127 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +class SubparticipantsController < ApplicationController + + require 'json/add/rails' + + before_filter :authentication + before_filter :block_anonymous_participants + before_filter :block_subparticipants + before_filter :check_json_contenttype, :only => :create + before_filter :check_parent, :only => [:show, :destroy, :update] + + def initialize + super + end + + def index + childs= @participant.childs + childs.each do |child| + @body << "subparticipants/" << child.id.to_s << "\n" + end unless childs.empty? + respond_to do |format| + format.text { render :text => @body, :content_type => "text/uri-list" } + end + end + + def show + subparticipant= Subparticipant.find(params[:id]) + body= show_render(subparticipant) + respond_to do |format| + format.json { render :json => JSON.pretty_generate(body) + "\r\n" } + format.xml { render :xml => body } + end + end + + def create + sender= @participant + begin + json_data= ActiveSupport::JSON.decode request.raw_post + rescue StandardError + raise Ecs::InvalidMessageException, "You have provided invalid JSON data (SubparticipantsController#create)." + end unless request.raw_post.empty? + subparticipant= Subparticipant.generate(sender, json_data) + body= show_render(subparticipant) + respond_to do |format| + format.json { render :json => JSON.pretty_generate(body) + "\r\n", :location => location(subparticipant) } + format.xml { render :xml => body, :location => location(subparticipant) } + end + end + + def update + begin + json_data= ActiveSupport::JSON.decode request.raw_post + rescue StandardError + raise Ecs::InvalidMessageException, "You have provided invalid JSON data (SubparticipantsController#update)." + end unless request.raw_post.empty? + sender= @participant + subparticipant= Subparticipant.find(params[:id]) + subparticipant.update__(sender, json_data, subparticipant) + body= show_render(subparticipant) + respond_to do |format| + format.json { render :json => JSON.pretty_generate(body) + "\r\n", :location => location(subparticipant) } + format.xml { render :xml => body, :location => location(subparticipant) } + end + end + + def destroy + subparticipant= Subparticipant.find(params[:id]) + subparticipant.participant.destroy + render :text => "", :layout => false, :status => 200, :content_type => :json + end + +private + + def show_render(subparticipant) + participant= subparticipant.participant + data = nil + data= \ + { + :name => participant.name, + :description => participant.description, + :auth_ids => participant.identities.map{|ident| {:auth_id=>ident.name, :desc=>ident.description}}, + :dns => participant.dns, + :email => participant.email, + :community_selfrouting => participant.community_selfrouting, + :events => participant.events_, + :communities => participant.communities.map{|c| c.name}, + :realm => subparticipant.realm, + } + data + end + + def check_parent + subparticipant= Subparticipant.find(params[:id]) + unless @participant.childs.include?(subparticipant) + raise Ecs::AuthorizationException, "You are not allowed to access this subparticipant because you are not its parent/creator." + end + end + + def check_communities + + end + + def location(subparticipant) + location = request.protocol + request.host + location += ":" + request.port.to_s unless [80, 443].include?(request.port) + location += request.headers["SCRIPT_NAME"] if request.headers.has_key?("SCRIPT_NAME") + location += request.path.gsub(/\/*$/,'') + "/" + subparticipant.id.to_s + location + end + +end diff --git a/app/helpers/subparticipants_helper.rb b/app/helpers/subparticipants_helper.rb new file mode 100644 index 0000000..8a08bcd --- /dev/null +++ b/app/helpers/subparticipants_helper.rb @@ -0,0 +1,19 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +module SubparticipantsHelper +end diff --git a/app/models/identity.rb b/app/models/identity.rb index 2c26c22..f6f3cb7 100644 --- a/app/models/identity.rb +++ b/app/models/identity.rb @@ -17,11 +17,20 @@ class Identity < ActiveRecord::Base + + require 'securerandom' + belongs_to :participant # TODO validate :participant_id # it's possible in rails 2.3.6 with :inverse_of validates_presence_of :name validates_uniqueness_of :name + + + def self.randomized_authid + SecureRandom.hex + end + end diff --git a/app/models/participant.rb b/app/models/participant.rb index 603a10c..a5f4cee 100644 --- a/app/models/participant.rb +++ b/app/models/participant.rb @@ -27,12 +27,19 @@ class Participant < ActiveRecord::Base has_many :communities, :through => :memberships has_many :identities, :dependent => :destroy has_many :events, :dependent => :destroy + has_many :childs, + :order => "id ASC", + :class_name => "Subparticipant", + :foreign_key => "parent_id", + :dependent => :destroy + has_one :subparticipant, :dependent => :destroy validates_presence_of :name, :organization_id validates_uniqueness_of :name accepts_nested_attributes_for :identities, :allow_destroy => true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } accepts_nested_attributes_for :communities, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } + accepts_nested_attributes_for :subparticipant, :allow_destroy => true #named_scope :reduced_attributes, :select => "name, description, dns, email" named_scope :without_anonymous, :conditions => { :participants => { :anonymous => false } } @@ -43,6 +50,7 @@ class Participant < ActiveRecord::Base named_scope :for_community, lambda { |community| { :joins => [:memberships => :community], :conditions => { :communities => { :id => community.id }}}} + named_scope :for_subparticipants # test if the participant is the initial sender of the message in question. def sender?(message) @@ -84,7 +92,6 @@ class Participant < ActiveRecord::Base participant.save end - def mid(community) Membership.for_participant_id_and_community_id(self, community.id).first.id end diff --git a/app/models/subparticipant.rb b/app/models/subparticipant.rb new file mode 100644 index 0000000..c764b33 --- /dev/null +++ b/app/models/subparticipant.rb @@ -0,0 +1,98 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +class Subparticipant < ActiveRecord::Base + + require 'securerandom' + + belongs_to :parent, + :class_name => "Participant", + :foreign_key => "parent_id" + + belongs_to :participant + + + def self.generate(sender, json_data) + auth_id= Identity.randomized_authid + data = process_json_data(sender, json_data) + params = { + "name" => "Subparticipant (\##{SecureRandom.hex}) from #{sender.name}", + "identities_attributes" => {"0"=>{"name"=>"#{auth_id}", "description"=>"Randomized authid"}}, + "community_ids" => data[:community_ids], + "description" => "", + "dns" => "N/A", + "organization_id" => sender.organization.id, + "email" => sender.email, + "ttl" => nil, + "anonymous" => false, + "community_selfrouting" => data[:community_selfrouting], + "events_" => data[:events], + "subparticipant_attributes" => { :realm => data[:realm] } + } + participant = Participant.new(params) + participant.save! + subp= participant.subparticipant + subp.parent= sender + subp.save! + participant.name= "Subparticipant (id:#{subp.id})" + participant.description= "Created from \"#{sender.name}\" (pid:#{sender.id})" + participant.save! + subp + end + + def update__(sender, json_data, subparticipant) + participant= subparticipant.participant + auth_id= "dummy" + data= process_json_data(sender, json_data) + params = { + "community_selfrouting" => data[:community_selfrouting], + "community_ids" => data[:community_ids], + "events_" => data[:events], + "subparticipant_attributes" => { :id => self.id.to_s, :realm => data[:realm] } + } + participant.update_attributes(params) + end + +private + + def process_json_data(sender, json_data) + Subparticipant::process_json_data(sender, json_data) + end + + def self.process_json_data(sender, json_data) + realm= json_data["realm"] ||= nil + community_selfrouting= json_data["community_selfrouting"] || false + events= json_data["events"] ||= false + if json_data["communities"] + community_ids= json_data["communities"].map do |comm| + erg= case + when comm.class == Fixnum + comm.to_s + when comm.class == String + (c= Community.find_by_name(comm)) ? c.id.to_s : nil + else + nil + end + end + end + community_ids ||= [] + community_ids.compact! + { :realm => realm, :community_selfrouting => community_selfrouting, :events => events, + :community_ids => community_ids } + end + +end diff --git a/config/environments/development.rb b/config/environments/development.rb index 3ff6b4d..c438cc7 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -41,5 +41,5 @@ class EcsLogger < Logger end end config.logger = EcsLogger.new(Rails.root.join("log",Rails.env + ".log")) -config.log_level = :info -config.logger.level = Logger::INFO +config.log_level = :debug +config.logger.level = Logger::DEBUG diff --git a/config/routes.rb b/config/routes.rb index eeae969..1b68e1a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,7 @@ ActionController::Routing::Routes.draw do |map| + map.namespace(:admin) do |admin| admin.resources :participants admin.resources :communities, :has_many => :participants @@ -34,6 +35,8 @@ ActionController::Routing::Routes.draw do |map| :only => [:index], :collection => { :fifo => [:get, :post] } map.resources :configs, :path_prefix => '/sys', :name_prefix => 'sys_', :only => [:index, :create] + map.resources :subparticipants, :path_prefix => '/sys', :name_prefix => 'sys_', + :only => [:index, :show, :create, :update, :destroy] begin Ressource.all.each do |r| diff --git a/db/migrate/20140525164346_create_subparticipants.rb b/db/migrate/20140525164346_create_subparticipants.rb new file mode 100644 index 0000000..6e2e49d --- /dev/null +++ b/db/migrate/20140525164346_create_subparticipants.rb @@ -0,0 +1,32 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +class CreateSubparticipants < ActiveRecord::Migration + def self.up + create_table :subparticipants do |t| + t.integer :participant_id + t.integer :parent_id + t.string :realm + + t.timestamps + end + end + + def self.down + drop_table :subparticipants + end +end diff --git a/db/schema.rb b/db/schema.rb index 74f16be..254e303 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130813144307) do +ActiveRecord::Schema.define(:version => 20140525164346) do create_table "auths", :force => true do |t| t.string "one_touch_hash" @@ -121,4 +121,12 @@ ActiveRecord::Schema.define(:version => 20130813144307) do add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" + create_table "subparticipants", :force => true do |t| + t.integer "participant_id" + t.integer "parent_id" + t.string "realm" + t.datetime "created_at" + t.datetime "updated_at" + end + end diff --git a/test/fixtures/subparticipants.yml b/test/fixtures/subparticipants.yml new file mode 100644 index 0000000..2097774 --- /dev/null +++ b/test/fixtures/subparticipants.yml @@ -0,0 +1,24 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +one: + realm: MyString + +two: + realm: MyString diff --git a/test/functional/subparticipants_controller_test.rb b/test/functional/subparticipants_controller_test.rb new file mode 100644 index 0000000..717fe52 --- /dev/null +++ b/test/functional/subparticipants_controller_test.rb @@ -0,0 +1,25 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +require 'test_helper' + +class SubparticipantsControllerTest < ActionController::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end diff --git a/test/unit/helpers/subparticipants_helper_test.rb b/test/unit/helpers/subparticipants_helper_test.rb new file mode 100644 index 0000000..40e31c9 --- /dev/null +++ b/test/unit/helpers/subparticipants_helper_test.rb @@ -0,0 +1,21 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +require 'test_helper' + +class SubparticipantsHelperTest < ActionView::TestCase +end diff --git a/test/unit/subparticipant_test.rb b/test/unit/subparticipant_test.rb new file mode 100644 index 0000000..a1f1cd1 --- /dev/null +++ b/test/unit/subparticipant_test.rb @@ -0,0 +1,42 @@ +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +# Copyright (C) 2014 Heiko Bernloehr (FreeIT.de). +# +# This file is part of ECS. +# +# ECS is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# ECS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with ECS. If not, see . + +require 'test_helper' + +class SubparticipantTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end -- cgit v1.2.3