Skip to content

Commit

Permalink
Merge pull request #28 from centosadmin/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
vladislav-yashin authored Feb 8, 2019
2 parents 1cee4b3 + 3c5e818 commit 6dca043
Show file tree
Hide file tree
Showing 39 changed files with 543 additions and 358 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# 0.3.0

* Hidden secret fields in settings
* Adapt tdlib commands for new version
* Add plugins deprecation warning
* Add proxy pool
* Add bot to robot contacts automatically
* Use unified proxies for bot and tdlib

# 0.2.0

* Add view telegram account permission
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ gem 'sidekiq-rate-limiter', git: 'https://github.com/centosadmin/sidekiq-rate-li
gem 'telegram-bot-ruby', '~> 0.8.6'
gem 'slack-ruby-bot'
gem 'celluloid-io'
gem 'tdlib-ruby', '~> 1.0'
gem 'tdlib-ruby', '2.0.0'
gem 'jwt'
gem 'filelock'
gem 'lazy_object', '~> 0.0.2'
gem 'patron'

group :test do
gem 'timecop'
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ This plugin provides common stuff to build redmine plugins that involve Slack/Te
* Ruby 2.3+
* Redmine 3.4+

### Upgrade from 0.2.0 to 0.3+

From 0.3.0 proxy settings are unified for tdlib and bot and there is support for multiple proxies.
If you have used proxies before, you should reassign it on plugin settings page.

### Upgrade from 0.1.0 to 0.2+

Webhook URL is changed in 0.2.0 because of webhook secret. You need to reinitialize webhook from plugin settings page.
Expand All @@ -22,6 +27,21 @@ Telegram support includes:
* Common client commands that utilize [tdlib-ruby](https://github.com/centosadmin/tdlib-ruby)
* [Telegram Login](https://core.telegram.org/widgets/login) to connect Redmine and Telegram accounts


### Proxy

You can set proxy pool on plugin settings page. Proxies are gonna be monitored for availability, and first working proxy will be taken for every request.

Proxy format is same to curl:

```bash
http://user:[email protected]:3128
socks5://user:[email protected]:9050
```

Only SOCKS5 and HTTP proxies are supported.
Note that tdlib supports only SOCKS5 proxies, so you should add at least one SOCKS5 proxy if you want tdlib to be proxied.

### Tdlib
In order to use tdlib client you need compiled [TDLib](https://github.com/tdlib/td).

Expand All @@ -45,6 +65,8 @@ To make telegram client working you should follow steps:
* Go to the plugin settings page
* Press "Authorize Telegram client" button and follow instructions

**IMPORTANT:** 2FA is not supported at the moment

### Bot API

It is necessary to register a bot and get its token.
Expand Down
29 changes: 18 additions & 11 deletions app/controllers/redmine_telegram_setup_controller.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
class RedmineTelegramSetupController < ApplicationController
include RedmineBots::Telegram::Tdlib::DependencyProviders::Authenticate
include RedmineBots::Telegram::Tdlib

def step_1
end

def step_2
begin
authenticate.(params)
rescue RedmineBots::Telegram::Tdlib::Authenticate::AuthenticationError => e
redirect_to plugin_settings_path('redmine_telegram_common'), alert: e.message
Rails.application.executor.wrap do
promise = RedmineBots::Telegram::Tdlib::Authenticate.(params).rescue do |error|
redirect_to plugin_settings_path('redmine_bots'), alert: error.message
end

ActiveSupport::Dependencies.interlock.permit_concurrent_loads { promise.wait! }
end
end

def authorize
begin
authenticate.(params)
save_phone_settings(phone_number: params['phone_number'])
redirect_to plugin_settings_path('redmine_bots'), notice: t('telegram_common.client.authorize.success')
rescue RedmineBots::Telegram::Tdlib::Authenticate::AuthenticationError => e
redirect_to plugin_settings_path('redmine_bots'), alert: e.message
Rails.application.executor.wrap do
promise = RedmineBots::Telegram::Tdlib::Authenticate.(params).then do
RedmineBots::Telegram::Tdlib::FetchAllChats.call
end.flat.then do
save_phone_settings(phone_number: params['phone_number'])
redirect_to plugin_settings_path('redmine_bots'), notice: t('redmine_bots.telegram.authorize.success')
end

ActiveSupport::Dependencies.interlock.permit_concurrent_loads { promise.wait! }
end
rescue TD::Error => error
redirect_to plugin_settings_path('redmine_bots'), alert: error.message
end

def reset
Expand Down
51 changes: 51 additions & 0 deletions app/controllers/telegram_proxies_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
class TelegramProxiesController < ApplicationController
before_action :check_admin

def index
@proxies = TelegramProxy.all

respond_to do |format|
format.js
end
end

def new
@proxy = TelegramProxy.new

respond_to do |format|
format.js
end
end

def update
params[:proxies].each do |params|
id, proxy_params = params[:id], filter_params(params)
proxy = id.present? ? TelegramProxy.find(id) : TelegramProxy.new
proxy.assign_attributes(proxy_params)
proxy.save
end

respond_to do |format|
format.js
end
end

def destroy
@proxy = TelegramProxy.find(params[:id])
@proxy.destroy

respond_to do |format|
format.js
end
end

private

def check_admin
raise Unauthorized unless User.current.admin?
end

def filter_params(params)
params.permit(:url)
end
end
42 changes: 42 additions & 0 deletions app/models/telegram_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class TelegramProxy < ActiveRecord::Base
enum protocol: %i[http socks5]

validates_presence_of :host, :port, :protocol

scope :alive, -> { where(alive: true) }

def assign_attributes(new_attributes)
attributes = new_attributes.stringify_keys
url = attributes.delete('url')
return super unless url

uri = URI(url)

protocol = uri.scheme.in?(self.class.protocols.keys) ? uri.scheme : nil

super(attributes.merge(user: uri.user, password: uri.password, host: uri.host, port: uri.port, protocol: protocol))
end

def url
return '' unless host.present?
"#{protocol}://#{user ? "#{[user, password.to_s].join(':')}@" : ''}#{[host, port].join(':')}"
end

def check!
status =
begin
connection.get('/').status
rescue Faraday::ClientError
nil
end
update(alive: status == 200)
end

private

def connection
Faraday.new('https://telegram.org') do |conn|
conn.adapter(:patron) { |adapter| adapter.proxy = url }
end
end
end
15 changes: 15 additions & 0 deletions app/views/settings/_redmine_bots.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
<%= render partial: 'settings/redmine_bots/deprecation_warning' %>

<% tabs = [
{name: 'slack', partial: 'settings/redmine_bots/slack', label: 'redmine_bots.label.slack'},
{name: 'telegram', partial: 'settings/redmine_bots/telegram', label: 'redmine_bots.label.telegram'},
] %>

<%= render_tabs tabs %>

<script>
$(".toggle-password").click(function() {
var input = $($(this).attr("toggle"));
if (input.attr("type") == "password") {
$(this).text('[Скрыть]');
input.attr("type", "text");
} else {
$(this).text('[Показать]');
input.attr("type", "password");
}
});
</script>
11 changes: 11 additions & 0 deletions app/views/settings/redmine_bots/_deprecation_warning.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<% if Redmine::Plugin.installed?('redmine_bots') %>
<% if RedmineBots.deprecated_plugins.present? %>
<h1 style="text-align: center">
!!! <%= "#{t 'redmine_bots.settings.deprecated_plugins'}#{RedmineBots.deprecated_plugins.join(', ')}" %> !!!
</h1>
<% end %>
<% else %>
<h1 style="text-align: center">
!!! <a href="https://github.com/centosadmin/redmine_bots" target="_blank">redmine_bots</a> not found !!!
</h1>
<% end %>
12 changes: 8 additions & 4 deletions app/views/settings/redmine_bots/_slack.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,30 @@
<label>
<%= t 'redmine_bots.settings.slack_client_secret' %>
</label>
<%= text_field_tag 'settings[slack_client_secret]', @settings['slack_client_secret'] %>
<%= text_field_tag 'settings[slack_client_secret]', @settings['slack_client_secret'], type: 'password' %>
<a href="javascript:void(0);" toggle="#settings_slack_client_secret" class="toggle-password">[Показать]</a>
</p>

<p>
<label>
<%= t 'redmine_bots.settings.slack_verification_token' %>
</label>
<%= text_field_tag 'settings[slack_verification_token]', @settings['slack_verification_token'] %>
<%= text_field_tag 'settings[slack_verification_token]', @settings['slack_verification_token'], type: 'password' %>
<a href="javascript:void(0);" toggle="#settings_slack_verification_token" class="toggle-password">[Показать]</a>
</p>

<p>
<label>
<%= t 'redmine_bots.settings.slack_oauth_token' %>
</label>
<%= text_field_tag 'settings[slack_oauth_token]', @settings['slack_oauth_token'] %>
<%= text_field_tag 'settings[slack_oauth_token]', @settings['slack_oauth_token'], type: 'password' %>
<a href="javascript:void(0);" toggle="#settings_slack_oauth_token" class="toggle-password">[Показать]</a>
</p>

<p>
<label>
<%= t 'redmine_bots.settings.slack_bot_oauth_token' %>
</label>
<%= text_field_tag 'settings[slack_bot_oauth_token]', @settings['slack_bot_oauth_token'] %>
<%= text_field_tag 'settings[slack_bot_oauth_token]', @settings['slack_bot_oauth_token'], type: 'password' %>
<a href="javascript:void(0);" toggle="#settings_slack_bot_oauth_token" class="toggle-password">[Показать]</a>
</p>
60 changes: 10 additions & 50 deletions app/views/settings/redmine_bots/_telegram.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,20 @@

<p>
<label for="settings_telegram_bot_token">Bot Token</label>
<%= text_field_tag 'settings[telegram_bot_token]', @settings['telegram_bot_token'], size: 50 %>
<%= text_field_tag 'settings[telegram_bot_token]', @settings['telegram_bot_token'], type: 'password', size: 50 %>
<a href="javascript:void(0);" toggle="#settings_telegram_bot_token" class="toggle-password">[Показать]</a>
</p>

<p>
<label for="settings_telegram_api_id">Api ID</label>
<%= text_field_tag 'settings[telegram_api_id]', @settings['telegram_api_id'], size: 50 %>
<%= text_field_tag 'settings[telegram_api_id]', @settings['telegram_api_id'], type: 'password', size: 50 %>
<a href="javascript:void(0);" toggle="#settings_telegram_api_id" class="toggle-password">[Показать]</a>
</p>

<p>
<label for="settings_telegram_api_hash">Api Hash</label>
<%= text_field_tag 'settings[telegram_api_hash]', @settings['telegram_api_hash'], size: 50 %>
<%= text_field_tag 'settings[telegram_api_hash]', @settings['telegram_api_hash'], type: 'password', size: 50 %>
<a href="javascript:void(0);" toggle="#settings_telegram_api_hash" class="toggle-password">[Показать]</a>
</p>

<p>
Expand All @@ -53,65 +56,22 @@

<hr>

<h3>Tdlib proxy (SOCKS5)</h3>
<h3><%= t 'redmine_bots.settings.telegram.proxy_settings' %></h3>

<p>
<label>
<%= t 'redmine_bots.settings.telegram.use_proxy' %>
<%= t 'redmine_bots.settings.telegram.tdlib_use_proxy' %>
</label>
<%= check_box_tag 'settings[tdlib_use_proxy]', '1', @settings['tdlib_use_proxy'] %>
</p>

<p>
<label for="settings_telegram_proxy_server">Server</label>
<%= text_field_tag 'settings[tdlib_proxy_server]', @settings['tdlib_proxy_server'], size: 50 %>
</p>

<p>
<label for="settings_telegram_proxy_port">Proxy port</label>
<%= text_field_tag 'settings[tdlib_proxy_port]', @settings['tdlib_proxy_port'], size: 50 %>
</p>

<p>
<label for="settings_telegram_proxy_user">Proxy user</label>
<%= text_field_tag 'settings[tdlib_proxy_user]', @settings['tdlib_proxy_user'], size: 50 %>
</p>

<p>
<label for="settings_telegram_proxy_password">Proxy password</label>
<%= text_field_tag 'settings[tdlib_proxy_password]', @settings['tdlib_proxy_password'], size: 50 %>
</p>

<hr>

<h3>Bot proxy</h3>

<p>
<label>
<%= t 'redmine_bots.settings.telegram.use_proxy' %>
<%= t 'redmine_bots.settings.telegram.bot_use_proxy' %>
</label>
<%= check_box_tag 'settings[bot_use_proxy]', '1', @settings['bot_use_proxy'] %>
</p>

<p>
<label for="settings_telegram_proxy_server">Server</label>
<%= text_field_tag 'settings[bot_proxy_server]', @settings['bot_proxy_server'], size: 50 %>
</p>
<%= link_to t('redmine_bots.settings.telegram.proxy_list'), telegram_proxies_path, remote: true %>

<p>
<label for="settings_telegram_proxy_port">Proxy port</label>
<%= text_field_tag 'settings[bot_proxy_port]', @settings['bot_proxy_port'], size: 50 %>
</p>

<p>
<label for="settings_telegram_proxy_user">Proxy user</label>
<%= text_field_tag 'settings[bot_proxy_user]', @settings['bot_proxy_user'], size: 50 %>
</p>

<p>
<label for="settings_telegram_proxy_password">Proxy password</label>
<%= text_field_tag 'settings[bot_proxy_password]', @settings['bot_proxy_password'], size: 50 %>
</p>

<hr>

Expand Down
8 changes: 8 additions & 0 deletions app/views/telegram_proxies/_item.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p id="<%= dom_id(proxy) %>">
<%= hidden_field_tag 'proxies[][id]', proxy.id %>
<%= text_field_tag 'proxies[][url]', proxy.url, style: 'width: 50%' %>

<% unless proxy.new_record? %>
<%= link_to l(:button_delete), telegram_proxy_destroy_path(id: proxy.id), remote: true, method: :delete %>
<% end %>
</p>
16 changes: 16 additions & 0 deletions app/views/telegram_proxies/_modal.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<%= form_tag telegram_proxies_path, remote: true, format: :js do %>
<div id="telegram-proxies" class="">
<% @proxies.each do |proxy| %>
<%= render partial: 'item', locals: { proxy: proxy } %>
<% end %>
</div>

<div>
<%= link_to l(:button_add), telegram_proxy_new_path, remote: true %>
</div>

<p>
<%= submit_tag l(:button_save) %>
</p>

<% end %>
1 change: 1 addition & 0 deletions app/views/telegram_proxies/destroy.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$('#<%= dom_id(@proxy) %>').remove();
Loading

0 comments on commit 6dca043

Please sign in to comment.