Skip to content

Commit

Permalink
Merge 12de9a5 into 40923c0
Browse files Browse the repository at this point in the history
  • Loading branch information
itowtips committed Apr 9, 2024
2 parents 40923c0 + 12de9a5 commit 0892791
Show file tree
Hide file tree
Showing 24 changed files with 627 additions and 2 deletions.
34 changes: 34 additions & 0 deletions app/controllers/cms/translate/access_logs_controller.rb
@@ -0,0 +1,34 @@
class Cms::Translate::AccessLogsController < ApplicationController
include Cms::BaseFilter
include Cms::CrudFilter

model Translate::AccessLog
navi_view "cms/translate/main/navi"

public

def download
@item = Translate::DownloadParam.new
@item.save_term = '1.day'
return if request.get? || request.head?

@item.attributes = params.require(:item).permit(:encoding, :save_term)
if @item.invalid?
render
return
end

cond = { site_id: @cur_site.id }
items = @model.where(cond)
@item.save_term_in_time.try do |from|
items = items.gte(created: from)
end
items = items.reorder(created: 1)

enumerable = items.enum_csv(cur_site: @cur_site, encoding: @item.encoding)
filename = "translate_access_logs_#{Time.zone.now.to_i}.csv"

response.status = 200
send_enum enumerable, type: enumerable.content_type, filename: filename
end
end
15 changes: 14 additions & 1 deletion app/controllers/concerns/translate/public_filter.rb
Expand Up @@ -11,8 +11,21 @@ def set_request_path_with_translate
return if !@cur_site.translate_enabled?
return if @cur_main_path !~ /^#{@cur_site.translate_location}\/.+?\//

deny_message = nil
if browser.bot?
Rails.logger.info("translate denied due to a bot access: #{request.user_agent}")
deny_message = "bot access: #{request.user_agent}"
end
if @cur_site.translate_deny_no_refererr? && request.referer.blank?
deny_message = "no referer access"
end
Translate::AccessLog.create_log!(@cur_site, request) do |item|
item.path = request_path
item.remote_addr = remote_addr
item.deny_message = deny_message
end

if deny_message.present?
Rails.logger.info("translate denied due to a #{deny_message}")
return
end

Expand Down
21 changes: 21 additions & 0 deletions app/jobs/translate/access_log/purge_job.rb
@@ -0,0 +1,21 @@
class Translate::AccessLog::PurgeJob < Cms::ApplicationJob

DEFAULT_THRESHOLD_DAYS = 60

before_perform :set_items

def model
Translate::AccessLog
end

def perform
count = @items.destroy_all
Rails.logger.info "#{I18n.l(@threshold.to_date)}以前の#{model.model_name.human}#{count}件削除しました。"
end

def set_items
@threshold = Time.zone.now - (site.translate_access_log_threshold || DEFAULT_THRESHOLD_DAYS).days
@items = model.site(site).lt(created: @threshold)
@items
end
end
18 changes: 18 additions & 0 deletions app/models/concerns/ss/addon/translate/site_setting.rb
Expand Up @@ -33,6 +33,10 @@ module Translate::SiteSetting
field :translate_google_api_request_count, type: Integer, default: 0
field :translate_google_api_request_word_count, type: Integer, default: 0

# access log
field :translate_referer_restriction, type: String, default: "disabled"
field :translate_access_log_threshold, type: Integer, default: 60

permit_params :translate_state
permit_params :translate_source_id
permit_params translate_target_ids: []
Expand All @@ -53,6 +57,9 @@ module Translate::SiteSetting
permit_params :translate_google_api_request_count
permit_params :translate_google_api_request_word_count

permit_params :translate_referer_restriction
permit_params :translate_access_log_threshold

validates :translate_api, presence: true, if: -> { translate_enabled? }
validate :validate_translate_source, if: -> { translate_api.present? }
validate :validate_translate_targets, if: -> { translate_api.present? }
Expand Down Expand Up @@ -122,6 +129,17 @@ def translate_url
::File.join(url, translate_location, "/")
end

def translate_referer_restriction_options
[
[I18n.t("translate.options.referer_restriction.disabled"), "disabled"],
[I18n.t("translate.options.referer_restriction.enabled"), "enabled"],
]
end

def translate_deny_no_refererr?
translate_referer_restriction == "enabled"
end

def find_translate_target(code)
translate_targets.select { |item| item.code == code }.first
end
Expand Down
62 changes: 62 additions & 0 deletions app/models/translate/access_log.rb
@@ -0,0 +1,62 @@
class Translate::AccessLog
include SS::Document
include SS::Reference::Site
include Cms::SitePermission

set_permission_name "cms_tools", :use

store_in_repl_master
index({ created: -1 })

field :path, type: String
field :remote_addr, type: String
field :user_agent, type: String
field :referer, type: String
field :deny_message, type: String

validates :path, presence: true

default_scope ->{ order_by(created: -1) }

def bot?
return false if user_agent.blank?
Browser.new(user_agent).bot?
end

class << self
def create_log!(site, request)
item = self.new
item.cur_site = site
item.path = request.path
item.user_agent = request.user_agent
item.remote_addr = request.remote_addr
item.referer = request.referer
yield item if block_given?
item.save!
item
end

def search(params = {})
criteria = self.where({})
return criteria if params.blank?

if params[:keyword].present?
criteria = criteria.keyword_in params[:keyword], :path
end
criteria
end

def enum_csv(options)
exporter = SS::Csv.draw(:export, context: self) do |drawer|
drawer.column :created
drawer.column :path
drawer.column :user_agent
drawer.column :remote_addr
drawer.column :referer
drawer.column :deny_message
end

exporter.enum(all, options)
end
end
end
25 changes: 25 additions & 0 deletions app/models/translate/download_param.rb
@@ -0,0 +1,25 @@
class Translate::DownloadParam
include ActiveModel::Model
include ActiveModel::Attributes

attr_accessor :cur_site, :cur_user

attribute :encoding, :string
attribute :save_term, :string

validates :encoding, presence: true, inclusion: { in: %w(Shift_JIS UTF-8), allow_blank: true }
validates :save_term, inclusion: { in: %w(1.day 1.month 1.year), allow_blank: true }

def save_term_options
%w(1.day 1.month 1.year).map do |v|
[ I18n.t("ss.options.duration.#{v.sub(".", "_")}"), v ]
end
end

def save_term_in_time(now = nil)
return if save_term.blank?

now ||= Time.zone.now
now - SS::Duration.parse(save_term)
end
end
12 changes: 12 additions & 0 deletions app/views/cms/translate/access_logs/_menu.html.erb
@@ -0,0 +1,12 @@
<nav class="nav-menu">
<% if params[:action] =~ /index/ %>
<% if @model.allowed?(:read, @cur_user, site: @cur_site, node: @cur_node) %>
<% download_url = url_for(action: :download_all) rescue (url_for(action: :download) rescue nil) %>
<% if download_url %>
<%= link_to(t('ss.links.download'), download_url, class: :download) %>
<% end %>
<% end %>
<% else %>
<%= link_to t('ss.links.back_to_index'), { action: :index }, class: "back-to-index" %>
<% end %>
</nav>
16 changes: 16 additions & 0 deletions app/views/cms/translate/access_logs/_show.html.erb
@@ -0,0 +1,16 @@
<dl class="see">
<dt><%= @model.t :path %></dt>
<dd><%= @item.path %></dd>

<dt><%= @model.t :remote_addr %></dt>
<dd><%= @item.remote_addr %></dd>

<dt><%= @model.t :user_agent %></dt>
<dd><%= @item.user_agent %></dd>

<dt><%= @model.t :referer %></dt>
<dd><%= @item.referer %></dd>

<dt><%= @model.t :deny_message %></dt>
<dd><%= @item.deny_message %></dd>
</dl>
27 changes: 27 additions & 0 deletions app/views/cms/translate/access_logs/download.html.erb
@@ -0,0 +1,27 @@
<%= form_for :item, url: { action: :download }, html: { method: :post } do |f| %>
<%= error_messages_for :item %>

<section class="main-box">
<header><h2><%= t "ss.download" %></h2></header>

<dl class="see">
<dt><%= t('ss.encoding') %></dt>
<dd>
<% %w(UTF-8 Shift_JIS).each do |encoding| %>
<label>
<%= radio_button_tag "#{f.object_name}[encoding]", encoding, encoding == 'UTF-8', {id: nil} %>
<%= t("ss.options.csv_encoding.#{encoding}") %>
</label>
<% end %>
</dd>

<dt><%= @item.class.human_attribute_name :save_term %></dt>
<dd><%= f.select :save_term, @item.save_term_options, include_blank: t("history.options.duration.all_save") %></dd>
</dl>
</section>

<footer class="send">
<%= f.submit t("ss.download"), class: :save %>
<%= f.button t("ss.buttons.cancel"), type: :reset, class: 'btn-default', onclick: "location.href='#{url_for(action: :index)}'; return false;" %>
</footer>
<% end %>
37 changes: 37 additions & 0 deletions app/views/cms/translate/access_logs/index.html.erb
@@ -0,0 +1,37 @@
<div class="index">
<div class="list-head">
<%= render template: "_search" %>
</div>

<ul class="list-items">
<% @items.each do |item| %>
<li class="list-item">
<nav class="tap-menu">
<%= link_to t('ss.links.show'), action: :show, id: item if item.allowed?(:read, @cur_user, site: @cur_site) %>
</nav>

<div class="info">
<span class="title">
<%= link_to item.path, { action: :show, id: item } %>
</span>

<div class="meta">
<span class="datetime"><%= ss_time_tag item.created %></span>
<span class="label"><%= @model.t :remote_addr %></span>
<span class="remote_addr"><%= item.remote_addr %></span>
<span class="label"><%= @model.t :user_agent %></span>
<span class="user_agent"><%= item.user_agent %></span>
<span class="label"><%= @model.t :referer %></span>
<span class="referer"><%= item.referer %></span>
<% if item.deny_message.present? %>
<span class="label"><%= @model.t :deny_message %></span>
<span class="deny-message" style="color: #b90000;"><%= item.deny_message %></span>
<% end %>
</div>
</div>
</li>
<% end %>
</ul>
</div>

<%= paginate @items if @items.try(:current_page) %>
1 change: 1 addition & 0 deletions app/views/cms/translate/main/_navi.html.erb
Expand Up @@ -3,6 +3,7 @@
<h3><%= link_to t("translate.text_cache"), cms_translate_text_caches_path %></h3>
<h3><%= link_to t("translate.site_setting"), cms_translate_site_setting_path %></h3>
<h3><%= link_to t("translate.lang"), cms_translate_langs_path %></h3>
<h3><%= link_to t("translate.access_log"), cms_translate_access_logs_path %></h3>
</nav>

<%= render partial: "cms/main/conf_navi" %>
@@ -0,0 +1,10 @@
<dl class="mod-request-word-limit see">
<dt><%= @model.t :translate_referer_restriction %><%= @model.tt :translate_referer_restriction %></dt>
<dd><%= f.select :translate_referer_restriction, @item.translate_referer_restriction_options %></dd>

<dt><%= @model.t :translate_access_log_threshold %><%= @model.tt :translate_access_log_threshold %></dt>
<dd>
<%= f.number_field :translate_access_log_threshold, min: 0 %>
<%= t("datetime.prompts.day") %>
</dd>
</dl>
@@ -0,0 +1,7 @@
<dl class="mod-request-word-limit see">
<dt><%= @model.t :translate_referer_restriction %></dt>
<dd><%= @item.label :translate_referer_restriction %></dd>

<dt><%= @model.t :translate_access_log_threshold %></dt>
<dd><%= @item.translate_access_log_threshold %></dd>
</dl>
12 changes: 12 additions & 0 deletions app/views/cms/translate/site_settings/edit.html.erb
Expand Up @@ -39,6 +39,18 @@
<% end %>
</div>

<div class="addon-views">
<%
addon_options = {}
addon_options[:id] = "addon-basic"
addon_options[:head] = I18n.t("translate.views.api_access_restriction")
%>
<% buf = render template: "_form_access_restriction", locals: { f: f, addon: addon_options } %>
<%= render "ss/crud/addon", addon: addon_options do %>
<%= buf %>
<% end %>
</div>

<footer class="send ss-sticky ss-sticky-bottom">
<% if @crud_buttons %>
<% @crud_buttons.call f %>
Expand Down
12 changes: 12 additions & 0 deletions app/views/cms/translate/site_settings/show.html.erb
Expand Up @@ -33,3 +33,15 @@
<%= buf %>
<% end %>
</div>

<div class="addon-views">
<%
addon_options = {}
addon_options[:id] = "addon-basic"
addon_options[:head] = I18n.t("translate.views.api_access_restriction")
%>
<% buf = render template: "_show_access_restriction", locals: { addon: addon_options } %>
<%= render "ss/crud/addon", addon: addon_options do %>
<%= buf %>
<% end %>
</div>
2 changes: 2 additions & 0 deletions config/locales/ss/ja.yml
Expand Up @@ -999,6 +999,8 @@ ja:
translate_google_api_request_word_count: APIリクエスト文字数
translate_api_request_word_limit: 文字数上限
translate_api_limit_exceeded_html: 制限超過時の表示HTML
translate_referer_restriction: リファラーによる制限
translate_access_log_threshold: 履歴保持期間
ss/addon/source_cleaner/site_setting:
source_cleaner_unwrap_tag_state: 不要なタグの削除
source_cleaner_remove_tag_state: 空のタグの削除
Expand Down

0 comments on commit 0892791

Please sign in to comment.