diff --git a/Gemfile b/Gemfile index c0efca90..119ab28e 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,8 @@ gem "chronic", "~> 0.10.2" gem 'redcarpet' +gem 'bcrypt' + gem 'activemodel-serializers-xml' gem 'actionpack-page_caching' diff --git a/Gemfile.lock b/Gemfile.lock index 3b605ae9..ff734410 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -84,6 +84,8 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) + bcrypt (3.1.20) + bcrypt (3.1.20-java) bigdecimal (3.1.8) bigdecimal (3.1.8-java) bindex (0.8.1) @@ -338,6 +340,7 @@ PLATFORMS DEPENDENCIES actionpack-page_caching activemodel-serializers-xml + bcrypt bootsnap capybara chronic (~> 0.10.2) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 173f93e5..e7f4f0b2 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -153,7 +153,7 @@ def users when :delete user = User.find(params[:user_id]) unless user.owner_of_owner? - Person.where(["user_id = ? AND project_id = ?", params[:user], @project.id]).delete_all + Person.where(user_id: params[:user], project_id: @project.id).delete_all end end @@ -182,7 +182,7 @@ def companies end end - def neww + def new authorize! :create_project, current_user @project = Project.new diff --git a/app/controllers/wiki_pages_controller.rb b/app/controllers/wiki_pages_controller.rb index 577b761e..fcb6e98e 100644 --- a/app/controllers/wiki_pages_controller.rb +++ b/app/controllers/wiki_pages_controller.rb @@ -56,7 +56,6 @@ def show def create @wiki_page = wiki_pages.build(wiki_page_params) @wiki_page.created_by = @logged_user - @wiki_page.current_revision = true puts @wiki_page.inspect if @wiki_page.save @@ -68,7 +67,6 @@ def create end def edit - puts "WIKIP=#{@wiki_page.inspect}" end def update @@ -84,14 +82,15 @@ def update end def destroy + flash[:message] = I18n.t "wiki_engine.success_deleting_wiki_page" + if params[:version].nil? - @wiki_page.where(:slug => id.slug).destroy + @wiki_page.destroy + redirect_to project_wiki_pages_path(@active_project) else - @wiki_page.where(:slug => id.slug, :revision_number => params[:version].to_i).destroy + @wiki_page.versions.where(revision_number: params[:version].to_i).destroy_all + redirect_to project_wiki_page_path(@active_project, id: @wiki_page.slug) end - - flash[:message] = I18n.t "wiki_engine.success_deleting_wiki_page" - redirect_to project_wiki_pages_path(@active_project) end def preview @@ -112,7 +111,8 @@ def find_main_wiki_page # Find all wiki pages. This is by default used only for list action. def find_wiki_pages - @wiki_pages = wiki_pages.where(current_revision: true).all + @wiki_pages = wiki_pages.where(revision_number: WikiPage.select('MAX(revision_number)') + .group(:slug)).all end # This is called when wiki page is not found. By default it display a page explaining @@ -142,9 +142,11 @@ def find_main_wiki_page end def load_related_object - begin - @wiki_page = wiki_pages.where(current_revision: true).where("slug = ? OR id = ?", params[:id], params[:id]).first - rescue ActiveRecord::RecordNotFound + @wiki_page = wiki_pages + .where("slug = ? OR id = ?", params[:id], params[:id]) + .order(revision_number: :desc) + .first + if @wiki_page.nil? redirect_back_or_default project_path(@active_project) return false end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0409bebb..5c149508 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -180,9 +180,14 @@ def actions_for_time_short(time) { name: I18n.t("delete"), url: project_time_path(time.project, id: time.id), cond: can?(:delete, time), data: { turbo_method: :delete, turbo_confirm: I18n.t("time_confirm_delete") } }] end - def actions_for_wiki_page(page) + def actions_for_wiki_page(page, version=nil) + if version.nil? + delete_path = project_wiki_page_path(page.project, id: page.slug) + else + delete_path = project_delete_version_wiki_page_path(page.project, id: page.slug, version: version.revision_number) + end [{ name: I18n.t("edit"), url: edit_project_wiki_page_path(page.project, id: page.slug), cond: can?(:edit, page) }, - { name: I18n.t("delete"), url: project_wiki_page_path(page.project, id: page.slug), cond: can?(:delete, page), data: { turbo_method: :delete, turbo_confirm: I18n.t("wiki_page_confirm_delete") } }] + { name: I18n.t("delete"), url: delete_path, cond: can?(:delete, page), data: { turbo_method: :delete, turbo_confirm: I18n.t("wiki_page_confirm_delete") } }] end def running_time_for_task(task) diff --git a/app/helpers/wiki_pages_helper.rb b/app/helpers/wiki_pages_helper.rb index 42b6c63b..99037147 100644 --- a/app/helpers/wiki_pages_helper.rb +++ b/app/helpers/wiki_pages_helper.rb @@ -58,7 +58,7 @@ def current_version(version) def versions(versions) versions.collect do |version| - [t("wiki_engine.version#{"_edited_by" unless version.user_name.blank?}", version: version.revision_number, user: version.user_name), project_wiki_page_path(@active_project, id: version.slug, version: version.revision_number)] + [t("wiki_engine.version#{"_edited_by" unless version.user_name.blank?}", version: version.revision_number, user: version.user_name), project_version_wiki_page_path(@active_project, id: version.slug, version: version.revision_number)] end end diff --git a/app/models/user.rb b/app/models/user.rb index 1ca0cdd8..245bde84 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -17,7 +17,7 @@ # along with this program. If not, see . #++ -require "digest/sha1" +require "bcrypt" class User < ApplicationRecord include Rails.application.routes.url_helpers @@ -101,7 +101,7 @@ def password def password=(value) return if @generated_password - salt = nil + salt = "" token = nil if value.empty? @@ -114,16 +114,7 @@ def password=(value) # Calculate a unique token with salt loop do # Grab a few random things... - tnow = Time.now() - sec = tnow.tv_usec - usec = tnow.tv_usec % 0x100000 - rval = rand() - roffs = rand(25) - - # Now we can calculate salt and token - salt = Digest::SHA1.hexdigest(sprintf("%s%08x%05x%.8f", rand(32767), sec, usec, rval))[roffs..roffs + 12] - token = Digest::SHA1.hexdigest(salt + value) - + token = BCrypt::Password.create(value) break if User.where({ token: token }).first.nil? end @@ -190,7 +181,7 @@ def self.authenticate(login, pass) end def valid_password(pass) - self.token == Digest::SHA1.hexdigest(self.salt + pass) + BCrypt::Password.new(self.token) == pass end # Helpers diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index cce752e8..9958801e 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -20,6 +20,7 @@ def process_create def process_destroy if self.revision_number == 0 + Activity.new_log(self, created_by, :delete) end end @@ -52,18 +53,14 @@ def new_version(params) new_version.current_revision = true if new_version.save - self.versions.update_all(current_revision: false) + self.versions.where.not(id: new_version.id).update_all(current_revision: false) end new_version end def object_url(host = nil) - if self.current_revision - project_wiki_page_url(project, id: self.friendly_id, only_path: host.nil?, host: host) - else - project_wiki_page_url(project, id: self.friendly_id, version: self.revision_number, only_path: host.nil?, host: host) - end + project_wiki_page_url(project, id: self.friendly_id, only_path: host.nil?, host: host) end # Search diff --git a/app/views/tasks/_form.html.haml b/app/views/tasks/_form.html.haml index 19205fb8..801850e5 100644 --- a/app/views/tasks/_form.html.haml +++ b/app/views/tasks/_form.html.haml @@ -1,26 +1,26 @@ -- if not form.object.new_record? and @no_show_list.nil? - %div - %label{for: "addTaskTaskList#{form.object.id}"} - = t('task_list') - \: - %span.label_required * - = form.select 'task_list_id', TaskList.select_list(@active_project), {}, id: "addTaskTaskList#{task.id}" - %div - %label{for: "addTaskText#{form.object.id}"} - = t('text') - \: - %span.label_required * - = form.text_area 'text', id: "addTaskText#{form.object.id}", class: 'short autofocus', rows: 10, cols: 40 - %div - %label{for: "taskAssignedTo#{form.object.id}"} - = t('assign_to') - \: - = assign_project_select_form form, 'task', 'assigned_to_id', @active_project, id: "taskAssignedTo#{form.object.id}" - %div - = form.check_box 'send_notification', '1', id: "taskSendNotification#{form.object.id}", class: 'checkbox' - %label.checkbox{for: "taskSendNotification#{form.object.id}"}= t('send_email_notification_to_user') - %div - %label{for: "addTaskHours"} - = t('estimated_hours') - \: - = form.text_field 'estimated_hours', id: 'addTaskHours', class: 'short' += error_messages_for :task +%div + %label{for: "addTaskTaskList#{form.object.id}"} + = t('task_list') + \: + %span.label_required * + = form.select 'task_list_id', TaskList.select_list(@active_project), {}, id: "addTaskTaskListSelect#{form.object.id}" +%div + %label{for: "addTaskText#{form.object.id}"} + = t('text') + \: + %span.label_required * + = form.text_area 'text', id: "addTaskText#{form.object.id}", class: 'short autofocus', rows: 10, cols: 40 +%div + %label{for: "taskAssignedTo#{form.object.id}"} + = t('assign_to') + \: + = form_assign_project_select form, 'assigned_to_id', @active_project, id: "taskAssignedTo#{form.object.id}" +%div + = form.check_box :'send_notification', id: "taskSendNotification#{form.object.id}", class: 'checkbox' + %label.checkbox{for: "taskSendNotification#{form.object.id}"}= t('send_email_notification_to_user') +%div + %label{for: "addTaskHours"} + = t('estimated_hours') + \: + = form.text_field 'estimated_hours', id: 'addTaskHours', class: 'short' diff --git a/app/views/tasks/edit.html.haml b/app/views/tasks/edit.html.haml index 4d337ffc..74e0bfbe 100644 --- a/app/views/tasks/edit.html.haml +++ b/app/views/tasks/edit.html.haml @@ -3,6 +3,6 @@ - @page_actions << {title: :add_task_list, :url=> new_project_task_list_path(@active_project)} = form_with(model: @task, url: project_task_list_task_path(@task.project, @task.task_list, @task), method: :put) do |form| - = render partial: 'form', locals: {form: form}, object: @task, + = render partial: 'form', locals: {form: form} %div %button.submit{type: "submit"}= t('edit_task') diff --git a/app/views/tasks/new.html.haml b/app/views/tasks/new.html.haml index fe076a84..63ad644e 100644 --- a/app/views/tasks/new.html.haml +++ b/app/views/tasks/new.html.haml @@ -2,7 +2,7 @@ - if can? :create_task_list, @active_project - @page_actions << {title: :add_task_list, :url=> new_project_task_list_path(@active_project)} -= form_with(model: @task, new_project_task_list_task_path(@task_list.project, @task_list) do |form| - = render partial: 'form', locals: {form: form}, object: @task += form_with(model: @task, url: new_project_task_list_task_path(@task_list.project, @task_list)) do |form| + = render partial: 'form', locals: {form: form} %div %button.submit{type: "submit"}= t('add_task') diff --git a/app/views/wiki_pages/show.html.haml b/app/views/wiki_pages/show.html.haml index 74d07ee0..2ddaedf9 100644 --- a/app/views/wiki_pages/show.html.haml +++ b/app/views/wiki_pages/show.html.haml @@ -4,6 +4,6 @@ - @page_actions << {title: :all_pages, url: list_project_wiki_pages_path(@active_project)} = render partial: 'wiki_page', object: @version .options - = action_list actions_for_wiki_page(@wiki_page) + = action_list actions_for_wiki_page(@wiki_page, @version) = select_tag :versions, options_for_versions_select(@versions), onchange: 'document.location.href = this.value;' = I18n.t('wiki_engine.last_modified_with_time', time: format_usertime(@version.created_at, :wiki_page_updated_format)) diff --git a/config/routes.rb b/config/routes.rb index d957e4bc..0a8c130b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -59,6 +59,8 @@ end end get 'wiki_pages/:id/:version', controller: 'wiki_pages', action: 'show', as: :version_wiki_page + delete 'wiki_pages/:id/:version', to: 'wiki_pages#destroy', as: :delete_version_wiki_page + resources :comments # Note: filter by category is done via "posts" on the category controller