diff --git a/app/assets/javascripts/projects.coffee b/app/assets/javascripts/projects.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/projects.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/projects.scss b/app/assets/stylesheets/projects.scss new file mode 100644 index 00000000..90634780 --- /dev/null +++ b/app/assets/stylesheets/projects.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Projects controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: https://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 37bcf595..a2fd03ce 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,7 +22,8 @@ class ApplicationController < ActionController::Base def user_not_authorized(exception) policy_name = exception.policy.class.to_s.underscore # flash[:alert] = "#{policy_name}.#{exception.query}" - flash[:alert] = "Unable to #{exception.query[0..-2]} #{policy_name.split("_")[0].capitalize}" + # flash[:alert] = "Unable to #{exception.query[0..-2]} #{policy_name.split("_")[0].capitalize}" + flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default redirect_to (request.referrer || root_path) end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb new file mode 100644 index 00000000..16f7be45 --- /dev/null +++ b/app/controllers/projects_controller.rb @@ -0,0 +1,71 @@ +class ProjectsController < ApplicationController + before_action :set_project, only: %i[ show edit update destroy ] + + # GET /projects or /projects.json + def index + @projects = authorize Project.all + end + + # GET /projects/1 or /projects/1.json + def show + authorize @project + end + + # GET /projects/new + def new + authorize @project = current_user.projects.new + end + + # GET /projects/1/edit + def edit + end + + # POST /projects or /projects.json + def create + authorize @project = Project.new(project_params) + + respond_to do |format| + if @project.save + format.html { redirect_to project_url(@project), notice: "Project was successfully created." } + format.json { render :show, status: :created, location: @project } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @project.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /projects/1 or /projects/1.json + def update + respond_to do |format| + if @project.update(project_params) + format.html { redirect_to project_url(@project), notice: "Project was successfully updated." } + format.json { render :show, status: :ok, location: @project } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @project.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /projects/1 or /projects/1.json + def destroy + @project.destroy + + respond_to do |format| + format.html { redirect_to projects_url, notice: "Project was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_project + @project = Project.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def project_params + params.require(:project).permit(:title, :description, :user_id) + end +end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb new file mode 100644 index 00000000..db5c5ce1 --- /dev/null +++ b/app/helpers/projects_helper.rb @@ -0,0 +1,2 @@ +module ProjectsHelper +end diff --git a/app/models/project.rb b/app/models/project.rb new file mode 100644 index 00000000..9b38b914 --- /dev/null +++ b/app/models/project.rb @@ -0,0 +1,3 @@ +class Project < ActiveRecord::Base + belongs_to :user +end diff --git a/app/models/user.rb b/app/models/user.rb index be50847a..0941e0b6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,7 @@ class User < ActiveRecord::Base validates :soft_token, presence: true, uniqueness: true has_many :canisters has_many :doodads + has_many :projects def icid stp = SoftTokenPrincipal.where(soft_token: self.soft_token).first_or_initialize diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb new file mode 100644 index 00000000..807f8996 --- /dev/null +++ b/app/policies/project_policy.rb @@ -0,0 +1,56 @@ +class ProjectPolicy + attr_reader :user, :project + + def initialize(user, project) + @user = user || User.new + @project = project + end + + class Scope + def initialize(user, scope) + @user = user + @scope = scope + end + + def resolve + if user.admin? + scope.all + else + scope.all + end + end + + private + + attr_reader :user, :scope + end + + def index? + true + end + + def show? + @user.admin? || @user == @project.user || @project.is_public? + end + + def create? + @user.admin? || true + end + + def new? + @user.signed_in? + end + + def edit? + @user.admin? || @user == @project.user || (@project.is_public? && @project.user.nil?) + end + + def update? + @user.admin? || @user == @project.user || (@project.is_public? && @project.user.nil?) + end + + def destroy? + @user.admin? || @user == @project.user || @project.user.nil? + end + +end diff --git a/app/views/layouts/_navigation_links.html.erb b/app/views/layouts/_navigation_links.html.erb index 9ff0139c..0d9912be 100644 --- a/app/views/layouts/_navigation_links.html.erb +++ b/app/views/layouts/_navigation_links.html.erb @@ -1,6 +1,7 @@