Merge branch 'master' into feature/rs-oauth
# Conflicts: # app/models/user.rb # config/routes.rb # db/schema.rb
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
class AccountController < ApplicationController
|
||||
before_action :require_user_signed_in
|
||||
before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
@current_section = :account
|
||||
|
||||
@@ -4,7 +4,7 @@ class Admin::UsersController < Admin::BaseController
|
||||
|
||||
def index
|
||||
ldap = LdapService.new
|
||||
@ou = params[:ou] || "kosmos.org"
|
||||
@ou = params[:ou] || Setting.primary_domain
|
||||
@orgs = ldap.fetch_organizations
|
||||
@pagy, @users = pagy(User.where(ou: @ou).order(cn: :asc))
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Contributions::DonationsController < ApplicationController
|
||||
before_action :require_user_signed_in
|
||||
before_action :authenticate_user!
|
||||
|
||||
# GET /donations
|
||||
# GET /donations.json
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Contributions::ProjectsController < ApplicationController
|
||||
before_action :require_user_signed_in
|
||||
before_action :authenticate_user!
|
||||
|
||||
# GET /contributions
|
||||
def index
|
||||
|
||||
@@ -2,6 +2,6 @@ class DashboardController < ApplicationController
|
||||
before_action :require_user_signed_in
|
||||
|
||||
def index
|
||||
@current_section = :dashboard
|
||||
@current_section = :services
|
||||
end
|
||||
end
|
||||
|
||||
17
app/controllers/discourse/sso_controller.rb
Normal file
17
app/controllers/discourse/sso_controller.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class Discourse::SsoController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
def connect
|
||||
secret = Setting.discourse_connect_secret
|
||||
sso = DiscourseApi::SingleSignOn.parse(request.query_string, secret)
|
||||
sso.external_id = current_user.id
|
||||
sso.email = current_user.email
|
||||
sso.username = current_user.cn
|
||||
sso.name = current_user.display_name
|
||||
sso.admin = current_user.is_admin?
|
||||
sso.sso_secret = secret
|
||||
|
||||
redirect_to sso.to_url("#{Setting.discourse_public_url}/session/sso_login"),
|
||||
allow_other_host: true
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class InvitationsController < ApplicationController
|
||||
before_action :require_user_signed_in, except: ["show"]
|
||||
before_action :authenticate_user!, except: ["show"]
|
||||
before_action :require_user_signed_out, only: ["show"]
|
||||
|
||||
# GET /invitations
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
require "rqrcode"
|
||||
|
||||
class WalletController < ApplicationController
|
||||
before_action :require_user_signed_in
|
||||
class Services::LightningController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :authenticate_with_lndhub
|
||||
before_action :set_current_section
|
||||
before_action :fetch_balance
|
||||
@@ -37,21 +37,21 @@ class WalletController < ApplicationController
|
||||
session[:ln_auth_token] = auth_token
|
||||
@ln_auth_token = auth_token
|
||||
end
|
||||
rescue
|
||||
# TODO add exception tracking
|
||||
rescue => e
|
||||
Sentry.capture_exception(e) if Setting.sentry_enabled?
|
||||
end
|
||||
|
||||
def set_current_section
|
||||
@current_section = :wallet
|
||||
@current_section = :services
|
||||
end
|
||||
|
||||
def fetch_balance
|
||||
lndhub = Lndhub.new
|
||||
data = lndhub.balance @ln_auth_token
|
||||
@balance = data["BTC"]["AvailableBalance"] rescue nil
|
||||
rescue
|
||||
rescue AuthError
|
||||
authenticate_with_lndhub(force_reauth: true)
|
||||
return nil if @fetch_balance_retried
|
||||
raise if @fetch_balance_retried
|
||||
@fetch_balance_retried = true
|
||||
fetch_balance
|
||||
end
|
||||
@@ -61,9 +61,9 @@ class WalletController < ApplicationController
|
||||
txs = lndhub.gettxs @ln_auth_token
|
||||
invoices = lndhub.getuserinvoices(@ln_auth_token).select{|i| i["ispaid"]}
|
||||
process_transactions(txs + invoices)
|
||||
rescue
|
||||
rescue AuthError
|
||||
authenticate_with_lndhub(force_reauth: true)
|
||||
return [] if @fetch_transactions_retried
|
||||
raise if @fetch_transactions_retried
|
||||
@fetch_transactions_retried = true
|
||||
fetch_transactions
|
||||
end
|
||||
@@ -78,6 +78,7 @@ class WalletController < ApplicationController
|
||||
tx["received"] = true
|
||||
else
|
||||
tx["amount_sats"] = tx["value"] || tx["amt"]
|
||||
tx["fee"] = tx["type"] == "paid_invoice" ? tx["fee"] : nil
|
||||
tx["datetime"] = Time.at(tx["timestamp"].to_i)
|
||||
tx["title"] = tx["type"] == "paid_invoice" ? "Sent" : "Received"
|
||||
tx["description"] = tx["memo"] || tx["description"]
|
||||
@@ -85,6 +86,10 @@ class WalletController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
# Handle an edge case where lndhub.go includes a failed payment in the
|
||||
# list, which wasn't actually booked
|
||||
txs.reject!{ |tx| tx["type"] == "paid_invoice" && tx["payment_preimage"].blank? }
|
||||
|
||||
txs.sort{ |a,b| b["datetime"] <=> a["datetime"] }
|
||||
end
|
||||
end
|
||||
30
app/controllers/services/remotestorage_controller.rb
Normal file
30
app/controllers/services/remotestorage_controller.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
class Services::RemotestorageController < ApplicationController
|
||||
before_action :require_user_signed_in
|
||||
before_action :require_service_enabled
|
||||
before_action :require_feature_enabled
|
||||
before_action :set_current_section
|
||||
|
||||
def dashboard
|
||||
# unless current_user.services_enabled.include?(:remotestorage)
|
||||
# redirect_to service_remotestorage_info_path
|
||||
# end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_feature_enabled
|
||||
unless Flipper.enabled?(:remotestorage, current_user)
|
||||
http_status :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def require_service_enabled
|
||||
unless Setting.remotestorage_enabled?
|
||||
http_status :not_found
|
||||
end
|
||||
end
|
||||
|
||||
def set_current_section
|
||||
@current_section = :services
|
||||
end
|
||||
end
|
||||
@@ -1,24 +1,54 @@
|
||||
require 'securerandom'
|
||||
|
||||
class SettingsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_main_nav_section
|
||||
before_action :set_settings_section, only: ['show', 'update']
|
||||
before_action :set_settings_section, only: [:show, :update, :update_email]
|
||||
before_action :set_user, only: [:show, :update, :update_email]
|
||||
|
||||
def index
|
||||
redirect_to setting_path(:profile)
|
||||
end
|
||||
|
||||
def show
|
||||
@user = current_user
|
||||
if @settings_section == "experiments"
|
||||
session[:shared_secret] ||= SecureRandom.base64(12)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@user = current_user
|
||||
@user.preferences.merge! user_params[:preferences]
|
||||
@user.save!
|
||||
@user.preferences.merge!(user_params[:preferences] || {})
|
||||
@user.display_name = user_params[:display_name]
|
||||
|
||||
redirect_to setting_path(@settings_section), flash: {
|
||||
success: 'Settings saved.'
|
||||
}
|
||||
if @user.save
|
||||
if @user.display_name && (@user.display_name != @user.ldap_entry[:display_name])
|
||||
LdapManager::UpdateDisplayName.call(@user.dn, user_params[:display_name])
|
||||
end
|
||||
|
||||
redirect_to setting_path(@settings_section), flash: {
|
||||
success: 'Settings saved.'
|
||||
}
|
||||
else
|
||||
@validation_errors = @user.errors
|
||||
render :show, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update_email
|
||||
if @user.valid_ldap_authentication?(email_params[:current_password])
|
||||
if @user.update email: email_params[:email]
|
||||
redirect_to setting_path(:account), flash: {
|
||||
notice: 'Please confirm your new address using the confirmation link we just sent you.'
|
||||
}
|
||||
else
|
||||
@validation_errors = @user.errors
|
||||
render :show, status: :unprocessable_entity
|
||||
end
|
||||
else
|
||||
redirect_to setting_path(:account), flash: {
|
||||
error: 'Password did not match your current password. Try again.'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def reset_password
|
||||
@@ -28,25 +58,78 @@ class SettingsController < ApplicationController
|
||||
redirect_to check_your_email_path, notice: msg
|
||||
end
|
||||
|
||||
def set_nostr_pubkey
|
||||
signed_event = nostr_event_params[:signed_event].to_h.symbolize_keys
|
||||
is_valid_id = NostrManager::ValidateId.call(signed_event)
|
||||
is_valid_sig = NostrManager::VerifySignature.call(signed_event)
|
||||
is_correct_content = signed_event[:content] == "Connect my public key to #{current_user.address} (confirmation #{session[:shared_secret]})"
|
||||
|
||||
unless is_valid_id && is_valid_sig && is_correct_content
|
||||
flash[:alert] = "Public key could not be verified"
|
||||
http_status :unprocessable_entity and return
|
||||
end
|
||||
|
||||
pubkey_taken = User.all_except(current_user).where(
|
||||
ou: current_user.ou, nostr_pubkey: signed_event[:pubkey]
|
||||
).any?
|
||||
|
||||
if pubkey_taken
|
||||
flash[:alert] = "Public key already in use for a different account"
|
||||
http_status :unprocessable_entity and return
|
||||
end
|
||||
|
||||
current_user.update! nostr_pubkey: signed_event[:pubkey]
|
||||
session[:shared_secret] = nil
|
||||
|
||||
flash[:success] = "Public key verification successful"
|
||||
http_status :ok
|
||||
rescue
|
||||
flash[:alert] = "Public key could not be verified"
|
||||
http_status :unprocessable_entity and return
|
||||
end
|
||||
|
||||
# DELETE /settings/nostr_pubkey
|
||||
def remove_nostr_pubkey
|
||||
current_user.update! nostr_pubkey: nil
|
||||
|
||||
redirect_to setting_path(:experiments), flash: {
|
||||
success: 'Public key removed from account'
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_main_nav_section
|
||||
@current_section = :settings
|
||||
end
|
||||
|
||||
def set_settings_section
|
||||
@settings_section = params[:section]
|
||||
allowed_sections = [:profile, :account, :lightning, :xmpp]
|
||||
|
||||
unless allowed_sections.include?(@settings_section.to_sym)
|
||||
redirect_to setting_path(:profile)
|
||||
def set_main_nav_section
|
||||
@current_section = :settings
|
||||
end
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(preferences: [
|
||||
:lightning_notify_sats_received,
|
||||
:xmpp_exchange_contacts_with_invitees
|
||||
])
|
||||
end
|
||||
def set_settings_section
|
||||
@settings_section = params[:section]
|
||||
allowed_sections = [:profile, :account, :lightning, :xmpp, :experiments]
|
||||
|
||||
unless allowed_sections.include?(@settings_section.to_sym)
|
||||
redirect_to setting_path(:profile)
|
||||
end
|
||||
end
|
||||
|
||||
def set_user
|
||||
@user = current_user
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:display_name, preferences: [
|
||||
:lightning_notify_sats_received,
|
||||
:xmpp_exchange_contacts_with_invitees
|
||||
])
|
||||
end
|
||||
|
||||
def email_params
|
||||
params.require(:user).permit(:email, :current_password)
|
||||
end
|
||||
|
||||
def nostr_event_params
|
||||
params.permit(signed_event: [
|
||||
:id, :pubkey, :created_at, :kind, :tags, :content, :sig
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -88,7 +88,7 @@ class SignupController < ApplicationController
|
||||
if session[:new_user].present?
|
||||
@user = User.new(session[:new_user])
|
||||
else
|
||||
@user = User.new(ou: "kosmos.org")
|
||||
@user = User.new(ou: Setting.primary_domain)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -98,7 +98,7 @@ class SignupController < ApplicationController
|
||||
|
||||
CreateAccount.call(
|
||||
username: @user.cn,
|
||||
domain: "kosmos.org",
|
||||
domain: Setting.primary_domain,
|
||||
email: @user.email,
|
||||
password: @user.password,
|
||||
invitation: @invitation
|
||||
|
||||
@@ -30,7 +30,7 @@ class WebhooksController < ApplicationController
|
||||
def notify_xmpp(address, amt_sats, memo)
|
||||
payload = {
|
||||
type: "normal",
|
||||
from: "kosmos.org", # TODO domain config
|
||||
from: Setting.primary_domain,
|
||||
to: address,
|
||||
subject: "Sats received!",
|
||||
body: "#{helpers.number_with_delimiter amt_sats} sats received in your Lightning wallet:\n> #{memo}"
|
||||
|
||||
16
app/controllers/well_known_controller.rb
Normal file
16
app/controllers/well_known_controller.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class WellKnownController < ApplicationController
|
||||
def nostr
|
||||
http_status :unprocessable_entity and return if params[:name].blank?
|
||||
domain = request.headers["X-Forwarded-Host"].presence || Setting.primary_domain
|
||||
@user = User.where(cn: params[:name], ou: domain).first
|
||||
http_status :not_found and return if @user.nil? || @user.nostr_pubkey.blank?
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {
|
||||
names: { "#{@user.cn}": @user.nostr_pubkey }
|
||||
}.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user