diff --git a/app/controllers/dmptemplates_controller.rb b/app/controllers/dmptemplates_controller.rb index d2be898..d8eab81 100644 --- a/app/controllers/dmptemplates_controller.rb +++ b/app/controllers/dmptemplates_controller.rb @@ -7,8 +7,9 @@ # GET /dmptemplates # GET /dmptemplates.json def admin_index + authorize Dmptemplate #institutional templates - @dmptemplates_own = authorize Dmptemplate.own_institutional_templates(current_user.organisation_id) + @dmptemplates_own = Dmptemplate.own_institutional_templates(current_user.organisation_id) #funders templates @dmptemplates_funders = Dmptemplate.funders_templates respond_to do |format| @@ -19,7 +20,8 @@ # GET /dmptemplates/1 # GET /dmptemplates/1.json def admin_template - @dmptemplate = authorize Dmptemplate.find(params[:id]) + @dmptemplate = Dmptemplate.find(params[:id]) + authorize @dmptemplate respond_to do |format| format.html # show.html.erb format.json { render json: @dmptemplate } @@ -31,7 +33,8 @@ # PUT /dmptemplates/1 # PUT /dmptemplates/1.json def admin_update - @dmptemplate = authorize Dmptemplate.find(params[:id]) + @dmptemplate = Dmptemplate.find(params[:id]) + authorize @dmptemplate @dmptemplate.description = params["template-desc"] respond_to do |format| if @dmptemplate.update_attributes(params[:dmptemplate]) @@ -48,7 +51,8 @@ # GET /dmptemplates/new # GET /dmptemplates/new.json def admin_new - @dmptemplate = authorize Dmptemplate.new + @dmptemplate = Dmptemplate.new + authorize @dmptemplate respond_to do |format| format.html # new.html.erb format.json { render json: @dmptemplate } @@ -58,9 +62,10 @@ # POST /dmptemplates # POST /dmptemplates.json def admin_create - @dmptemplate = authorize Dmptemplate.new(params[:dmptemplate]) + @dmptemplate = Dmptemplate.new(params[:dmptemplate]) @dmptemplate.organisation_id = current_user.organisation.id @dmptemplate.description = params['template-desc'] + authorize @dmptemplate respond_to do |format| if @dmptemplate.save format.html { redirect_to admin_template_dmptemplate_path(@dmptemplate), notice: I18n.t('org_admin.templates.created_message') } @@ -77,7 +82,8 @@ # DELETE /dmptemplates/1 # DELETE /dmptemplates/1.json def admin_destroy - @dmptemplate = authorize Dmptemplate.find(params[:id]) + @dmptemplate = Dmptemplate.find(params[:id]) + authorize @dmptemplate @dmptemplate.destroy respond_to do |format| format.html { redirect_to admin_index_dmptemplate_path } @@ -91,7 +97,8 @@ #show and edit a phase of the template def admin_phase - @phase = authorize Phase.find(params[:id]) + authorize Dmptemplate + @phase = Phase.find(params[:id]) if !params.has_key?(:version_id) then @edit = 'false' #check for the most recent published version, if none is available then return the most recent one @@ -134,7 +141,8 @@ #preview a phase def admin_previewphase - @version = authorize Version.find(params[:id]) + authorize Dmptemplate + @version = Version.find(params[:id]) respond_to do |format| format.html end @@ -143,7 +151,8 @@ #add a new phase to a template def admin_addphase - @dmptemplate = authorize Dmptemplate.find(params[:id]) + authorize Dmptemplate + @dmptemplate = Dmptemplate.find(params[:id]) @phase = Phase.new if @dmptemplate.phases.count == 0 then @phase.number = '1' @@ -158,7 +167,8 @@ #create a phase def admin_createphase - @phase = authorize Phase.new(params[:phase]) + authorize Dmptemplate + @phase = Phase.new(params[:phase]) @phase.description = params["phase-desc"] @version = @phase.versions.build @version.title = "#{@phase.title} v.1" @@ -179,7 +189,8 @@ #update a phase of a template def admin_updatephase - @phase = authorize Phase.find(params[:id]) + authorize Dmptemplate + @phase = Phase.find(params[:id]) @phase.description = params["phase-desc"] respond_to do |format| if @phase.update_attributes(params[:phase]) @@ -194,7 +205,8 @@ #delete a version, sections and questions def admin_destroyphase - @phase = authorize Phase.find(params[:phase_id]) + authorize Dmptemplate + @phase = Phase.find(params[:phase_id]) @dmptemplate = @phase.dmptemplate @phase.destroy respond_to do |format| @@ -235,7 +247,8 @@ #clone a version of a template def admin_cloneversion - @old_version = authorize Version.find(params[:version_id]) + authorize Dmptemplate + @old_version = Version.find(params[:version_id]) @version = @old_version.amoeba_dup @phase = @version.phase respond_to do |format| @@ -251,7 +264,8 @@ #delete a version, sections and questions def admin_destroyversion - @version = authorize Version.find(params[:version_id]) + authorize Dmptemplate + @version = Version.find(params[:version_id]) @phase = @version.phase @version.destroy respond_to do |format| @@ -265,7 +279,8 @@ #create a section def admin_createsection - @section = authorize Section.new(params[:section]) + authorize Dmptemplate + @section = Section.new(params[:section]) @section.description = params["section-desc"] respond_to do |format| if @section.save @@ -281,7 +296,8 @@ #update a section of a template def admin_updatesection - @section = authorize Section.find(params[:id]) + authorize Dmptemplate + @section = Section.find(params[:id]) @section.description = params["section-desc-#{params[:id]}"] @version = @section.version @phase = @version.phase @@ -299,7 +315,8 @@ #delete a section and questions def admin_destroysection - @section = authorize Section.find(params[:section_id]) + authorize Dmptemplate + @section = Section.find(params[:section_id]) @version = @section.version @phase = @version.phase @section.destroy @@ -314,7 +331,8 @@ #create a question def admin_createquestion - @question = authorize Question.new(params[:question]) + authorize Dmptemplate + @question = Question.new(params[:question]) @question.guidance = params["new-question-guidance"] @question.default_value = params["new-question-default-value"] respond_to do |format| @@ -330,7 +348,8 @@ #update a question of a template def admin_updatequestion - @question = authorize Question.find(params[:id]) + authorize Dmptemplate + @question = Question.find(params[:id]) @question.guidance = params["question-guidance-#{params[:id]}"] @question.default_value = params["question-default-value-#{params[:id]}"] @section = @question.section @@ -349,7 +368,8 @@ #delete a version, sections and questions def admin_destroyquestion - @question = authorize Question.find(params[:question_id]) + authorize Dmptemplate + @question = Question.find(params[:question_id]) @section = @question.section @version = @section.version @phase = @version.phase @@ -364,7 +384,8 @@ #SUGGESTED ANSWERS #create suggested answers def admin_createsuggestedanswer - @suggested_answer = authorize SuggestedAnswer.new(params[:suggested_answer]) + authorize Dmptemplate + @suggested_answer = SuggestedAnswer.new(params[:suggested_answer]) respond_to do |format| if @suggested_answer.save format.html { redirect_to admin_phase_dmptemplate_path(:id => @suggested_answer.question.section.version.phase_id, :version_id => @suggested_answer.question.section.version_id, :section_id => @suggested_answer.question.section_id, :question_id => @suggested_answer.question.id, :edit => 'true'), notice: I18n.t('org_admin.templates.created_message') } @@ -379,7 +400,8 @@ #update a suggested answer of a template def admin_updatesuggestedanswer - @suggested_answer = authorize SuggestedAnswer.find(params[:id]) + authorize Dmptemplate + @suggested_answer = SuggestedAnswer.find(params[:id]) @question = @suggested_answer.question @section = @question.section @version = @section.version @@ -398,7 +420,8 @@ #delete a suggested answer def admin_destroysuggestedanswer - @suggested_answer = authorize SuggestedAnswer.find(params[:suggested_answer]) + authorize Dmptemplate + @suggested_answer = SuggestedAnswer.find(params[:suggested_answer]) @question = @suggested_answer.question @section = @question.section @version = @section.version @@ -414,7 +437,8 @@ #create a guidance def admin_createguidance - @question = authorize Question.find(params[:question][:id]) + authorize Dmptemplate + @question = Question.find(params[:question][:id]) @guidance = Guidance.new(params[:guidance]) @guidance.question_id = @question.id #@question.guidance = params["new-question-guidance"] @@ -432,7 +456,8 @@ #update a guidance of a template def admin_updateguidance - @question = authorize Question.find(params[:id]) + authorize Dmptemplate + @question = Question.find(params[:id]) @question.guidance = params["question-guidance-#{params[:id]}"] @question.default_value = params["question-default-value-#{params[:id]}"] @section = @question.section @@ -451,7 +476,8 @@ #delete a version, sections and guidance def admin_destroyguidance - @question = authorize Question.find(params[:question_id]) + authorize Dmptemplate + @question = Question.find(params[:question_id]) @section = @question.section @version = @section.version @phase = @version.phase diff --git a/app/controllers/guidance_groups_controller.rb b/app/controllers/guidance_groups_controller.rb index 1cc1dac..4c0c900 100644 --- a/app/controllers/guidance_groups_controller.rb +++ b/app/controllers/guidance_groups_controller.rb @@ -4,7 +4,8 @@ # GET /guidance_groups/1 # GET /guidance_groups/1.json def admin_show - @guidance_group = authorize GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) + authorize @guidance_group respond_to do |format| format.html format.json { render json: @guidance_group } @@ -14,7 +15,8 @@ # GET add new guidance groups def admin_new - @guidance_group = authorize GuidanceGroup.new + @guidance_group = GuidanceGroup.new + authorize @guidance_group respond_to do |format| format.html # new.html.erb format.json { render json: @guidance } @@ -25,7 +27,8 @@ # POST /guidance_groups # POST /guidance_groups.json def admin_create - @guidance_group = authorize GuidanceGroup.new(params[:guidance_group]) + @guidance_group = GuidanceGroup.new(params[:guidance_group]) + authorize @guidance_group @guidance_group.organisation_id = current_user.organisation_id if params[:save_publish] @guidance_group.published = true @@ -45,14 +48,16 @@ # GET /guidance_groups/1/edit def admin_edit - @guidance_group = authorize GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) + authorize @guidance_group end # PUT /guidance_groups/1 # PUT /guidance_groups/1.json def admin_update - @guidance_group = authorize GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) + authorize @guidance_group @guidance_group.organisation_id = current_user.organisation_id respond_to do |format| if @guidance_group.update_attributes(params[:guidance_group]) @@ -68,7 +73,8 @@ # PUT /guidance_groups/1 def admin_update_publish - @guidance_group = authorize GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) + authorize @guidance_group @guidance_group.organisation_id = current_user.organisation_id @guidance_group.published = true @@ -87,7 +93,8 @@ # DELETE /guidance_groups/1 # DELETE /guidance_groups/1.json def admin_destroy - @guidance_group = authorize GuidanceGroup.find(params[:id]) + @guidance_group = GuidanceGroup.find(params[:id]) + authorize @guidance_group @guidance_group.destroy respond_to do |format| format.html { redirect_to admin_index_guidance_path, notice: I18n.t('org_admin.guidance_group.destroyed_message') } diff --git a/app/controllers/guidances_controller.rb b/app/controllers/guidances_controller.rb index 1227036..b126f0d 100644 --- a/app/controllers/guidances_controller.rb +++ b/app/controllers/guidances_controller.rb @@ -2,7 +2,8 @@ # GET /guidances # GET /guidances.json def admin_index - @guidances = authorize Guidance.by_organisation(current_user.organisation_id) + authorize Guidance + @guidances = policy_scope(Guidance) @guidance_groups = GuidanceGroup.where('organisation_id = ?', current_user.organisation_id ) respond_to do |format| format.html # index.html.erb @@ -13,18 +14,17 @@ # GET /guidances/1 # GET /guidances/1.json def admin_show - if user_signed_in? && current_user.is_org_admin? then - @guidance = Guidance.find(params[:id]) - - respond_to do |format| - format.html # show.html.erb - format.json { render json: @guidance } - end - end + @guidance = Guidance.find(params[:id]) + authorize @guidance + respond_to do |format| + format.html # show.html.erb + format.json { render json: @guidance } + end end def admin_new - @guidance = authorize Guidance.new + @guidance = Guidance.new + authorize @guidance @dmptemplates = Dmptemplate.funders_and_own_templates(current_user.organisation_id) @phases = nil @dmptemplates.each do |template| @@ -101,7 +101,8 @@ # GET /guidances/1/edit def admin_edit - @guidance = authorize Guidance.find(params[:id]) + @guidance = Guidance.find(params[:id]) + authorize @guidance @dmptemplates = Dmptemplate.funders_and_own_templates(current_user.organisation_id) @phases = nil @dmptemplates.each do |template| @@ -140,7 +141,8 @@ # POST /guidances # POST /guidances.json def admin_create - @guidance = authorize Guidance.new(params[:guidance]) + @guidance = Guidance.new(params[:guidance]) + authorize @guidance @guidance.text = params["guidance-text"] @guidance.question_id = params["question_id"] if @guidance.published == true then @@ -164,7 +166,8 @@ # PUT /guidances/1 # PUT /guidances/1.json def admin_update - @guidance = authorize Guidance.find(params[:id]) + @guidance = Guidance.find(params[:id]) + authorize @guidance @guidance.text = params["guidance-text"] @guidance.question_id = params["question_id"] respond_to do |format| @@ -182,7 +185,8 @@ # DELETE /guidances/1 # DELETE /guidances/1.json def admin_destroy - @guidance = authorize Guidance.find(params[:id]) + @guidance = Guidance.find(params[:id]) + authorize @guidance @guidance.destroy respond_to do |format| format.html { redirect_to admin_index_guidance_path } diff --git a/app/controllers/token_permission_types_controller.rb b/app/controllers/token_permission_types_controller.rb index d4b7470..67499da 100644 --- a/app/controllers/token_permission_types_controller.rb +++ b/app/controllers/token_permission_types_controller.rb @@ -2,8 +2,7 @@ def index - logger.debug "#{current_user}" - authorize TokenPermissionType.first + authorize TokenPermissionType @user = current_user respond_to do |format| format.html diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb new file mode 100644 index 0000000..ea84308 --- /dev/null +++ b/app/policies/application_policy.rb @@ -0,0 +1,55 @@ +class ApplicationPolicy + attr_reader :user, :record + attr_reader :user, :record + + def initialize(user, record) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @record = record + end + + def index? + false + end + + def show? + scope.where(:id => record.id).exists? + end + + def create? + false + end + + def new? + create? + end + + def update? + false + end + + def edit? + update? + end + + def destroy? + false + end + + def scope + Pundit.policy_scope!(user, record.class) + end + + class Scope + attr_reader :user, :scope + + def initialize(user, scope) + @user = user + @scope = scope + end + + def resolve + scope = [] + end + end +end \ No newline at end of file diff --git a/app/policies/dmptemplate_policy.rb b/app/policies/dmptemplate_policy.rb index 61c6a9c..4c20bd9 100644 --- a/app/policies/dmptemplate_policy.rb +++ b/app/policies/dmptemplate_policy.rb @@ -1,4 +1,4 @@ -class DmptemplatePolicy +class DmptemplatePolicy < ApplicationPolicy attr_reader :user, :dmptemplate def initialize(user, dmptemplate) @@ -11,11 +11,11 @@ end def admin_template? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.organisation_id == user.organisation_id) end def admin_update? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.organisation_id == user.organisation_id) end def admin_new? @@ -23,83 +23,83 @@ end def admin_create? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.organisation_id == user.organisation_id) end def admin_destroy? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.organisation_id == user.organisation_id) end def admin_phase? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.dmptemplate.organisation_id == user.organisation_id) end def admin_previewphase? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.dmptemplate.organisation_id == user.organisation_id) end def admin_addphase? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.dmptemplate.organisation_id == user.organisation_id) end def admin_createphase? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.dmptemplate.organisation_id == user.organisation_id) end def admin_updatephase? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.dmptemplate.organisation_id == user.organisation_id) end def admin_destroyphase? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.dmptemplate.organisation_id == user.organisation_id) end def admin_updateversion? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_cloneversion? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_destroyversion? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_createsection? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_updatesection? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_destroysection? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_createquestion? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_updatequestion? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_destroyquestion? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.section.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_createsuggestedanswer? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.question.section.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_updatesuggestedanswer? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.question.section.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_destroysuggestedanswer? - user.can_modify_templates? + user.can_modify_templates? && (dmptemplate.question.section.version.phase.dmptemplate.organisation_id == user.organisation_id) end def admin_createguidance? @@ -114,4 +114,10 @@ user.can_modify_templates? end + class Scope < Scope + def resolve + scope.where(organisation_id: user.organisation_id) + end + end + end \ No newline at end of file diff --git a/app/policies/guidance_group_policy.rb b/app/policies/guidance_group_policy.rb new file mode 100644 index 0000000..682ba39 --- /dev/null +++ b/app/policies/guidance_group_policy.rb @@ -0,0 +1,43 @@ +class GuidanceGroupPolicy < ApplicationPolicy + attr_reader :user, :guidance_group + + def initialize(user, guidance_group) + @user = user + @guidance_group = guidance_group + end + + def admin_show? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + def admin_edit? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + def admin_update? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + def admin_update_publish? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + def admin_new? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + def admin_create? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + def admin_destroy? + user.can_modify_guidance? && (guidance_group.organisation_id == user.organisation_id) + end + + class Scope < Scope + def resolve + scope.where(organisation_id: user.organisation_id) + end + end + +end \ No newline at end of file diff --git a/app/policies/guidance_groups_policy.rb b/app/policies/guidance_groups_policy.rb deleted file mode 100644 index 9829a8a..0000000 --- a/app/policies/guidance_groups_policy.rb +++ /dev/null @@ -1,37 +0,0 @@ -class GuidanceGroupsPolicy - attr_reader :user, :guidance - - def initialize(user, guidance) - @user = user - @guidance = guidance - end - - def admin_show? - user.can_modify_guidance? - end - - def admin_edit? - user.can_modify_guidance? - end - - def admin_update? - user.can_modify_guidance? - end - - def admin_update_publish? - user.can_modify_guidance? - end - - def admin_new? - user.can_modify_guidance? - end - - def admin_create? - user.can_modify_guidance? - end - - def admin_destroy? - user.can_modify_guidance? - end - -end \ No newline at end of file diff --git a/app/policies/guidance_policy.rb b/app/policies/guidance_policy.rb index 7f83bfe..7efa7ef 100644 --- a/app/policies/guidance_policy.rb +++ b/app/policies/guidance_policy.rb @@ -1,4 +1,4 @@ -class GuidancePolicy +class GuidancePolicy < ApplicationPolicy attr_reader :user, :guidance def initialize(user, guidance) @@ -7,15 +7,15 @@ end def admin_show? - user.can_modify_guidance? + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) end def admin_edit? - user.can_modify_guidance? + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) end def admin_update? - user.can_modify_guidance? + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) end def admin_index? @@ -31,7 +31,12 @@ end def admin_destroy? - user.can_modify_guidance? + user.can_modify_guidance? && guidance.in_group_belonging_to?(user.organisation_id) end + class Scope < Scope + def resolve + scope = Guidance.by_organisation(user.organisation_id) + end + end end \ No newline at end of file diff --git a/app/policies/organisation_policy.rb b/app/policies/organisation_policy.rb index cd574bb..12e98eb 100644 --- a/app/policies/organisation_policy.rb +++ b/app/policies/organisation_policy.rb @@ -1,4 +1,4 @@ -class OrganisationPolicy +class OrganisationPolicy < ApplicationPolicy attr_reader :user, :organisation def initialize(user, organisation) @@ -7,15 +7,15 @@ end def admin_show? - user.can_modify_org_details? + user.can_modify_org_details? && (user.organisation_id == organisation.id) end def admin_edit? - user.can_modify_org_details? + user.can_modify_org_details? && (user.organisaiton_id == organisation.id) end def admin_update? - user.can_modify_org_details? + user.can_modify_org_details? && (user.organisaiton_id == organisation.id) end end \ No newline at end of file diff --git a/app/policies/token_permission_type_policy.rb b/app/policies/token_permission_type_policy.rb index a8767c9..513d20e 100644 --- a/app/policies/token_permission_type_policy.rb +++ b/app/policies/token_permission_type_policy.rb @@ -1,4 +1,4 @@ -class TokenPermissionTypePolicy +class TokenPermissionTypePolicy < ApplicationPolicy attr_reader :user, :token_permission_type def initialize(user, token_permission_type) diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 7a9a58e..071f474 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -1,4 +1,4 @@ -class UserPolicy +class UserPolicy < ApplicationPolicy attr_reader :user def initialize(user, users) @@ -13,4 +13,10 @@ user.can_use_api? && user.can_grant_permissions? end + class Scope < Scope + def resolve + scope.where(organisation_id: user.organisation_id) + end + end + end \ No newline at end of file diff --git a/public/403.html b/public/403.html index 88188d7..87c6555 100644 --- a/public/403.html +++ b/public/403.html @@ -104,11 +104,11 @@

-Welcome to DMPonline version 4 +Welcome to DMPonline version 4

-

Something has gone wrong.

-

To report this error please contact us on dmponline@dcc.ac.uk

+

You are not authorized to view this resource.

+

To report this as an error please contact us on dmponline@dcc.ac.uk