Commit 6ae47abc authored by mh's avatar mh
Browse files

first shot of jabber support

parent 1ada63b1
# 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/
//= require userlist
//= require qrtoggle
function enableDelete() {
document.getElementById('enable_delete_form').style.display = 'none';
document.getElementById('delete_form').style.display = 'block';
}
......@@ -64,13 +64,23 @@ class ApplicationController < ActionController::Base
end
helper_method :recovery_email_set?
def resource_enabled?(resource)
session[:possible_resources][resource].present?
end
helper_method :resource_enabled?
def any_resources_enabled?
['jabber'].any?{|r| resource_enabled?(r) }
end
helper_method :any_resources_enabled?
def admin?
@is_admin ||= Admin::Enabled && Admin::Admins.include?(current_user)
end
helper_method :admin?
def feature_toggle?(feature)
(Config['features'] || []).include?(feature)
def feature_toggle?(*features)
features.any?{|f| (Config['features'] || []).include?(f) }
end
helper_method :feature_toggle?
......
......@@ -132,6 +132,86 @@ module ApiBackend
get(['mail', 'storagehosts'], {})
end
def self.jabber_get_jid(email, jid, host = nil, include_deleted = false)
get(['jabber', 'info'], {
'email' => email,
'jid' => jid,
'host' => host,
'include_deleted' => include_deleted,
})
end
def self.jabber_delete_jid(email, jid, password)
post(['jabber', 'delete'], {
'email' => email,
'jid' => jid,
'account_password' => password,
})
end
def self.jabber_create(email, jid_alias = nil, domain = nil)
post(['jabber', 'create'], {
'email' => email,
'jid_alias' => jid_alias,
'domain' => domain,
})
end
def self.jabber_reset_password(email, jid)
post(['jabber', 'reset_password'], {
'email' => email,
'jid' => jid,
})
end
def self.jabber_purge_jid(jid)
post(['jabber', 'purge'], {
'jid' => jid,
})
end
def self.jabber_get_jids(email = nil)
get(['jabber', 'list'], {'email' => email })
end
def self.jabber_domains_public
get(['jabber_domains', 'list_public'], {})['domains']
end
def self.jabber_domains
get(['jabber_domains', 'list'])
end
def self.jabber_get_domain(domain)
get(['jabber_domains', 'get'],{
'domain' => domain,
})
end
def self.jabber_create_domain(domain, host, ispublic = false)
post(['jabber_domains', 'create'],{
'domain' => domain,
'host' => host,
'ispublic' => ispublic,
})
end
def self.jabber_get_jabberhosts
get(['jabber_domains', 'jabberhosts'])
end
def self.jabber_update_domain(domain, host, ispublic = false)
post(['jabber_domains', 'update'],{
'domain' => domain,
'host' => host,
'ispublic' => ispublic,
})
end
def self.jabber_delete_domain(domain)
post(['jabber_domains', 'delete'],{
'domain' => domain,
})
end
def self.change_password(user, old, pw)
post(['users', 'change_password'], {"email"=>user, "current_password" => old, "new_password" => pw})
end
......
class JabberController < ApplicationController
before_action :ensure_jabber_enabled?
before_action :fetch_public_domains, :only => ['index']
def index
api_res = ApiBackend.jabber_get_jids(current_user)
@jids = api_res['jids']
@possible_jids = api_res['possible_jids']
rescue ApiBackend::ApiError
flash[:notice] = :failed
redirect_to root_path
end
def show
@jid = ApiBackend.jabber_get_jid(current_user, params[:jid])
rescue ApiBackend::ApiError
flash[:notice] = :failed
redirect_to jabber_path
end
def reset_password
@jid = ApiBackend.jabber_reset_password(current_user, params[:jid])
render :show
rescue ApiBackend::ApiError
flash[:notice] = :failed
redirect_to jabber_path
end
def delete
ApiBackend.jabber_delete_jid(current_user, params[:jid], params[:password])
redirect_to jabber_path and return
rescue ApiBackend::ApiError => e
if ['failed','auth_fail'].include?(e.api_msg)
flash[:notice] = e.api_msg
else
flash[:notice] = :failed
end
redirect_to jabber_path
end
def create
@jid = ApiBackend.jabber_create(current_user, params[:jid_alias], params[:domain])
render :show
rescue ApiBackend::ApiError => e
flash[:notice] = e.api_msg
redirect_to jabber_path
end
private
def fetch_public_domains
@public_jabber_domains = ApiBackend.jabber_domains_public
rescue ApiBackend::ApiError
flash[:notice] = :failed
redirect_to root_path
end
def ensure_jabber_enabled?
unless resource_enabled?('jabber')
flash[:notice] = :service_not_available
redirect_to root_path
end
end
def qr
@qr ||= if @jid.present? && @jid['password'].present?
RQRCode::QRCode.new(@jid['password'], :size => 10, :level => :h)
else
nil
end
end
helper_method :qr
end
......@@ -118,6 +118,7 @@ class SessionsController < ApplicationController
session[:mail_crypt_recovery_token] = nil
session[:mail_crypt_enabled] = res['mail_crypt_enabled']
session[:recovery_email_set] = res['recovery_email_set']
session[:possible_resources] = Hash(res['possible_resources'])
if CountIpFails
Rails.cache.write(client_auth_key, 0, expires_in: 10.minutes)
end
......
<h3><%= @page_title = t(:manage_jabber) %></h3>
<p>
<%= simple_format(t(:jabber_help)) %>
</p>
<br/>
<% unless @jids.empty? -%>
<h4><%= t(:your_jabber_ids) %></h4>
<table class="userlist">
<thead>
<tr>
<th><%= t(:jabber_id) %></th>
<th><%= t(:last_used) %></th>
<th><%= t(:actions) %></th>
</tr>
</thead>
<tbody>
<% @jids.each do |jid,lastlogin| %>
<tr>
<td>
<%= link_to(jid, "#{jabber_path}/#{URI::escape(jid)}") %>
</td>
<td>
<%= lastlogin.present? ? lastlogin : t(:never_used) %>
</td>
<td>
<%= link_to(t(:generate_new_password), "#{jabber_path}/#{URI::escape(jid)}/reset_password", method: :post) %>
</td>
</tr>
<%- end %>
</tbody>
</table>
<br/>
<% end -%>
<% if @possible_jids.present? -%>
<% @possible_jids.each do |jid| -%>
<h4><%= t(:create_jid) %> - <%= jid %></h4>
<%= t(:create_jid_help) %>
<p>
</p>
<%= form_tag(jabber_path, method: "post") do %>
<%= hidden_field_tag(:jid, jid) %>
<%= submit_tag t(:create) %>
<% end
end
end -%>
<% if @jids.present? -%>
<h4><%= t(:create_public_jid) %></h4>
<p>
<%= t(:create_public_jid_help) %>
</p>
<%= form_tag(jabber_path, method: "post") do %>
<%= label_tag(:jid_alias, t(:jid_alias)) %>
<%= text_field_tag(:jid_alias) %>
<%= label_tag(:domain, t(:domain)) %>
<%= select_tag :domain, options_for_select(@public_jabber_domains) %>
<%= submit_tag t(:create) %>
<% end
end -%>
<h3><%= @page_title = "#{t(:manage_jabber_id)} - #{@jid['jid']}" %></h3>
<b><%= t(:jabber_id) %>: <%= @jid['jid'] %></b><br/>
<%= t(:last_used) + ': ' + ((ll=@jid['lastlogin']).present? ? ll : t(:never_used)) %><br/>
<% if qr -%>
<br/>
<p>
<h4><%= t(:jabber_password) %></h4>
<div class="app-password"><%= @jid['password'] %></div>
<br />
<b><a href="#" id="qr-toggle"><%= t(:qr_code) %></a></b>
<div id="qr-hidden">
<div class="qr-field"><%= raw(qr.as_html) %></div>
</div><br/>
<br/>
<%= t(:jabber_password_help) %>
</p>
<% end %>
<p>
<%= form_tag("#{jabber_path}/#{URI::escape(@jid['jid'])}/reset_password", method: "post") do %>
<%= submit_tag t(:generate_new_password) %>
<% end -%>
</p>
<%= link_to t(:back), jabber_path %>
&nbsp;|&nbsp;
<a href="#" id="enable_delete_form"/><%= t(:delete) %></a>
<div id="delete_form" style="display:none">
<br />
<%= form_tag("#{jabber_path}/#{URI::escape(@jid['jid'])}/delete", method: "post") do %>
<%= hidden_field_tag(:jid, @jid['jid']) %>
<%= label_tag(:pass, t(:your_main_pw)) %></td><td><%= password_field_tag(:password, nil, placeholder: t(:enter_your_current_pw)) %>
<%= submit_tag(t :delete) %>
<% end -%>
</div>
<h3><%= @page_title = t(:main_title) %></h3>
<ul class="menu">
<li><%= link_to (t :change_password), password_path %>
<li><%= link_to t(:change_password), password_path %>
<br /><%= t(:change_password_short_help) %>
</li>
<% if feature_toggle?('2fa') %>
......@@ -29,3 +29,13 @@
<li style='padding-top:10px'><%= link_to (t :delete_account) , delete_account_path %>
</li>
</ul>
<% if any_resources_enabled? -%>
<h3><%= t(:services) %></h3>
<ul class="menu">
<% if resource_enabled?('jabber') -%>
<li><%= link_to t(:manage_jabber), jabber_path %>
<br/><%= t(:manage_jabber_short_help) %>
</li>
<% end -%>
</ul>
<% end -%>
......@@ -11,4 +11,4 @@ Rails.application.config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
Rails.application.config.assets.precompile += %w( sessions.js password.js signup.js users.js domains.js mail_crypt.js app_passwords.js )
Rails.application.config.assets.precompile += %w( sessions.js password.js signup.js users.js domains.js mail_crypt.js app_passwords.js jabber.js )
......@@ -116,6 +116,25 @@ en:
enter_captcha: "Please copy the following letters into the field below."
admin_lock: "Lock account"
services: Services
manage_jabber: "Manage Jabber Ids"
manage_jabber_id: "Manage Jabber Id"
manage_jabber_short_help: "Jabber is a federated instant messaging service to easily chat with your friends on any device. Manage your accounts and create further identities."
jabber_help: "Jabber is a federated instant messaging service to easily chat with your friends on any device. It is also known as XMPP, though we favor the name jabber. Within the Jabber network you have a Jabber Id (short Jid), that looks similar to an emailaddress. You can create a Jabber Id connected to your account and hence matching your emailaddress. Additionally, you can also create additional identites dedicated domains.<br/><br/>A Jabber Id at immerda comes with a pre-generated and unique password, which can only be used for the given Jabber id. If you can't remember the pre-generated password, you can simply generate a new one.<br/><br/>To use Jabber, there are numerous desktop clients (e.g. <a href=\"https://gajim.org/\">Gajim</a>) or mobile clients (e.g. <a href=\"https://conversations.im/\">Conversations</a> or <a href=\"https://chatsecure.org/\">ChatSecure</a>). Find more options on our <a href=\"https://wiki.immerda.ch/index.php/immerda:Jabber\">Wiki</a>. We recommend you to use an additional end-to-end encryption to establish secure end-to-end connections with your friends. Like you would use OpenPGP for emails. Most common used ones are OTR or OMEMO and are fully supported by above clients.<br/><br/>Jabber also features multi-user chatrooms (called MUCs), so multiple folks can chat together on a topic. You are able to create such rooms on the conference server (conference.YOUR_JABBER_DOMAIN) and configure them according to your needs. E.g. you might want to keep it invite-only or password protected. A popular MUC is the one of the immerda project: immerda@conference.imsg.ch - join it once you activated and connected with your Jabber id. Happy to chat there with the community around our services!"
jabber_id: Jabber Id
actions: Actions
generate_new_password: Generate new password
create_jid: Create Jabber Id
create_jid_help: "You can create a Jabber Id matching your email address. This makes it easy to connect both by email and jabber. You will receive a pre-generated password for your Jabber Id, which is only valid for the given identity. If you forget it, simply generate a new password and the old one will be gone."
create_public_jid: Create additional Jabber Ids
create_public_jid_help: 'While the Jabber Id matching your email address, might help to more easily connect with others, you might also not always want to reveal this connection. For that we are running dedicated Jabber domains, where no emailaddresses ever exist and you can create additional Jabber Ids for your needs. The principle is: "first come - first served."'
jid_alias: Jabber Id Alias
domain: Domain
jabber_password: Jabber Password
jabber_password_help: A Jabber Id at immerda comes with a pre-generated and unique password, which can only be used for the given Jabber Id. The new password is shown in the next section and you can copy it to your Jabber client. If you want to use your Jabber Id on multiple systems or devices, you must store this password now. We are not able to show it again to you later. You will have to create a new one, if you can't remember it. To make it easier to copy the password to mobile devices you can also scan a QR code.
jid_exists_already: Jabber Id is already taken
failed: A failure happened!
activerecord:
errors:
......
......@@ -22,6 +22,16 @@ Rails.application.routes.draw do
get '/app_passwords', to: 'app_passwords#show'
post '/app_passwords', to: 'app_passwords#edit'
get '/jabber', to: 'jabber#index'
post '/jabber', to: 'jabber#create'
constraints(:jid => /[^\/]+/) do
get '/jabber/:jid', to: 'jabber#show'
get '/jabber/:jid/reset_password', to: 'jabber#show'
post '/jabber/:jid/reset_password', to: 'jabber#reset_password'
get '/jabber/:jid/delete', to: 'jabber#show'
post '/jabber/:jid/delete', to: 'jabber#delete'
end
get '/login/:handoff', to: 'sessions#new'
post '/login/:handoff', to: 'sessions#create'
get '/login/:handoff/:handoff_instance', to: 'sessions#new'
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment