Compare commits
12 Commits
feature/ld
...
6ddeacb779
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ddeacb779 | |||
|
78aff3d796
|
|||
|
8f600f44bd
|
|||
|
819ecf6ad8
|
|||
|
670b2da1ef
|
|||
|
ed5c5b3081
|
|||
| 4ee6bfddfa | |||
|
8b60890061
|
|||
|
0367450c4b
|
|||
|
e6f5623c7f
|
|||
| 367f566ccb | |||
|
80e69df75c
|
@@ -11,6 +11,8 @@ DISCOURSE_CONNECT_SECRET='discourse_connect_ftw'
|
||||
|
||||
EJABBERD_API_URL='http://xmpp.example.com/api'
|
||||
|
||||
MASTODON_PUBLIC_URL='http://example.social'
|
||||
|
||||
LNDHUB_API_URL='http://localhost:3026'
|
||||
LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org'
|
||||
LNDHUB_PUBLIC_KEY='024cd3be18617f39cf645851e3ba63f51fc13f0bb09e3bb25e6fd4de556486d946'
|
||||
|
||||
@@ -3,7 +3,7 @@ class Services::ChatController < Services::BaseController
|
||||
before_action :require_service_available
|
||||
|
||||
def show
|
||||
@service_enabled = current_user.services_enabled.include?(:xmpp)
|
||||
@service_enabled = current_user.service_enabled?(:xmpp)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -3,7 +3,7 @@ class Services::MastodonController < Services::BaseController
|
||||
before_action :require_service_available
|
||||
|
||||
def show
|
||||
@service_enabled = current_user.services_enabled.include?(:mastodon)
|
||||
@service_enabled = current_user.service_enabled?(:mastodon)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -5,7 +5,7 @@ class Services::RemotestorageController < Services::BaseController
|
||||
|
||||
# Dashboard
|
||||
def show
|
||||
# unless current_user.services_enabled.include?(:remotestorage)
|
||||
# unless current_user.service_enabled?(:remotestorage)
|
||||
# redirect_to service_remotestorage_info_path
|
||||
# end
|
||||
@rs_auths = current_user.remote_storage_authorizations
|
||||
|
||||
@@ -7,14 +7,15 @@ class WebfingerController < ApplicationController
|
||||
resource = params[:resource]
|
||||
|
||||
if resource && @useraddress = resource.match(/acct:(.+)/)&.[](1)
|
||||
@username, @org = @useraddress.split("@")
|
||||
@username, @domain = @useraddress.split("@")
|
||||
|
||||
unless Rails.env.development?
|
||||
# Allow different domains (e.g. localhost:3000) in development only
|
||||
head 404 and return unless @org == Setting.primary_domain
|
||||
head 404 and return unless @domain == Setting.primary_domain
|
||||
end
|
||||
|
||||
unless User.where(cn: @username.downcase, ou: Setting.primary_domain).any?
|
||||
unless @user = User.where(ou: Setting.primary_domain)
|
||||
.find_by(cn: @username.downcase)
|
||||
head 404 and return
|
||||
end
|
||||
|
||||
@@ -28,12 +29,50 @@ class WebfingerController < ApplicationController
|
||||
private
|
||||
|
||||
def webfinger
|
||||
links = [];
|
||||
jrd = {
|
||||
subject: "acct:#{@user.address}",
|
||||
aliases: [],
|
||||
links: []
|
||||
}
|
||||
|
||||
# TODO check if storage service is enabled for user, not just globally
|
||||
links << remotestorage_link if Setting.remotestorage_enabled
|
||||
if Setting.mastodon_enabled && @user.service_enabled?(:mastodon)
|
||||
# https://docs.joinmastodon.org/spec/webfinger/
|
||||
jrd[:aliases] += mastodon_aliases
|
||||
jrd[:links] += mastodon_links
|
||||
end
|
||||
|
||||
{ "links" => links }
|
||||
if Setting.remotestorage_enabled && @user.service_enabled?(:remotestorage)
|
||||
# https://datatracker.ietf.org/doc/draft-dejong-remotestorage/
|
||||
jrd[:links] << remotestorage_link
|
||||
end
|
||||
|
||||
jrd
|
||||
end
|
||||
|
||||
def mastodon_aliases
|
||||
[
|
||||
"#{Setting.mastodon_public_url}/@#{@user.cn}",
|
||||
"#{Setting.mastodon_public_url}/users/#{@user.cn}"
|
||||
]
|
||||
end
|
||||
|
||||
def mastodon_links
|
||||
[
|
||||
{
|
||||
rel: "http://webfinger.net/rel/profile-page",
|
||||
type: "text/html",
|
||||
href: "#{Setting.mastodon_public_url}/@#{@user.cn}"
|
||||
},
|
||||
{
|
||||
rel: "self",
|
||||
type: "application/activity+json",
|
||||
href: "#{Setting.mastodon_public_url}/users/#{@user.cn}"
|
||||
},
|
||||
{
|
||||
rel: "http://ostatus.org/schema/1.0/subscribe",
|
||||
template: "#{Setting.mastodon_public_url}/authorize_interaction?uri={uri}"
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
def remotestorage_link
|
||||
@@ -41,9 +80,9 @@ class WebfingerController < ApplicationController
|
||||
storage_url = "#{Setting.rs_storage_url}/#{@username}"
|
||||
|
||||
{
|
||||
"rel" => "http://tools.ietf.org/id/draft-dejong-remotestorage",
|
||||
"href" => storage_url,
|
||||
"properties" => {
|
||||
rel: "http://tools.ietf.org/id/draft-dejong-remotestorage",
|
||||
href: storage_url,
|
||||
properties: {
|
||||
"http://remotestorage.io/spec/version" => "draft-dejong-remotestorage-13",
|
||||
"http://tools.ietf.org/html/rfc6749#section-4.2" => auth_url,
|
||||
"http://tools.ietf.org/html/rfc6750#section-2.3" => nil, # access token via a HTTP query parameter
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class CreateLdapUserJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(username, domain, email, hashed_pw)
|
||||
def perform(username:, domain:, email:, hashed_pw:, confirmed: false)
|
||||
dn = "cn=#{username},ou=#{domain},cn=users,dc=kosmos,dc=org"
|
||||
attr = {
|
||||
objectclass: ["top", "account", "person", "extensibleObject"],
|
||||
@@ -12,6 +12,10 @@ class CreateLdapUserJob < ApplicationJob
|
||||
userPassword: hashed_pw
|
||||
}
|
||||
|
||||
if confirmed
|
||||
attr[:serviceEnabled] = Setting.default_services
|
||||
end
|
||||
|
||||
ldap_client.add(dn: dn, attributes: attr)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ class XmppExchangeContactsJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(inviter, invitee)
|
||||
return unless inviter.services_enabled.include?("xmpp") &&
|
||||
invitee.services_enabled.include?("xmpp") &&
|
||||
return unless inviter.service_enabled?(:xmpp) &&
|
||||
invitee.service_enabled?(:xmpp) &&
|
||||
inviter.preferences[:xmpp_exchange_contacts_with_invitees]
|
||||
|
||||
ejabberd = EjabberdApiClient.new
|
||||
|
||||
@@ -206,4 +206,9 @@ class Setting < RailsSettings::Base
|
||||
#
|
||||
# field :email_imap_port, type: :string,
|
||||
# default: ENV["EMAIL_IMAP_PORT"].presence || 993
|
||||
|
||||
def self.default_services
|
||||
# TODO Make configurable from respective service settings page
|
||||
%w[ discourse gitea mastodon mediawiki xmpp ]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -93,9 +93,7 @@ class User < ApplicationRecord
|
||||
LdapManager::UpdateEmail.call(dn: self.dn, address: self.email)
|
||||
else
|
||||
# E-Mail from signup confirmed (i.e. account activation)
|
||||
|
||||
# TODO Make configurable, only activate globally enabled services
|
||||
enable_service %w[ discourse gitea mediawiki xmpp ]
|
||||
enable_default_services
|
||||
|
||||
# TODO enable in development when we have easy setup of ejabberd etc.
|
||||
return if Rails.env.development? || !Setting.ejabberd_enabled?
|
||||
@@ -133,7 +131,7 @@ class User < ApplicationRecord
|
||||
|
||||
def mastodon_address
|
||||
return nil unless Setting.mastodon_enabled?
|
||||
"#{self.cn}@#{Setting.mastodon_address_domain}"
|
||||
"#{self.cn.gsub("-", "_")}@#{Setting.mastodon_address_domain}"
|
||||
end
|
||||
|
||||
def valid_attribute?(attribute_name)
|
||||
@@ -141,6 +139,10 @@ class User < ApplicationRecord
|
||||
self.errors[attribute_name].blank?
|
||||
end
|
||||
|
||||
def enable_default_services
|
||||
enable_service Setting.default_services
|
||||
end
|
||||
|
||||
def ln_create_invoice(payload)
|
||||
lndhub = Lndhub.new
|
||||
lndhub.authenticate self
|
||||
@@ -178,6 +180,10 @@ class User < ApplicationRecord
|
||||
ldap_entry[:services_enabled] || []
|
||||
end
|
||||
|
||||
def service_enabled?(name)
|
||||
services_enabled.map(&:to_sym).include?(name.to_sym)
|
||||
end
|
||||
|
||||
def enable_service(service)
|
||||
current_services = services_enabled
|
||||
new_services = Array(service).map(&:to_s)
|
||||
|
||||
@@ -35,11 +35,15 @@ class CreateAccount < ApplicationService
|
||||
@invitation.update! invited_user_id: user_id, used_at: DateTime.now
|
||||
end
|
||||
|
||||
# TODO move to confirmation
|
||||
# (and/or add email_confirmed to entry and use in login filter)
|
||||
def add_ldap_document
|
||||
hashed_pw = Devise.ldap_auth_password_builder.call(@password)
|
||||
CreateLdapUserJob.perform_later(@username, @domain, @email, hashed_pw)
|
||||
CreateLdapUserJob.perform_later(
|
||||
username: @username,
|
||||
domain: @domain,
|
||||
email: @email,
|
||||
hashed_pw: hashed_pw,
|
||||
confirmed: @confirmed
|
||||
)
|
||||
end
|
||||
|
||||
def create_lndhub_account(user)
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
<p>
|
||||
There's something to do for everyone, especially non-programmers! For
|
||||
example, we need more help with graphics, UI/UX design, and
|
||||
content/copywriting. We also need moderators for social media. And beta
|
||||
testers for our software. The list doesn't end there.
|
||||
content/copywriting. Also, testing any of our software and reporting
|
||||
issues you encounter along the way is very valuable.
|
||||
</p>
|
||||
<p>
|
||||
A good way to get started is to join one of our
|
||||
@@ -43,7 +43,7 @@
|
||||
</p>
|
||||
<p>
|
||||
We have run two 6-month trials so far, with the next trial period
|
||||
starting sometime in Q1 2024. Watch your email for notifications about it!
|
||||
starting sometime in Q2 2024. Watch your email for notifications about it!
|
||||
</p>
|
||||
</section>
|
||||
<% end %>
|
||||
|
||||
@@ -98,7 +98,17 @@
|
||||
description: "The official Web app",
|
||||
icon_path: "/img/logos/icon_mastodon-2.svg",
|
||||
links: [
|
||||
["Launch", "https://kosmos.social"]
|
||||
["Launch", "https://kosmos.social"],
|
||||
["GitHub", "https://github.com/mastodon/mastodon"]
|
||||
]
|
||||
) %>
|
||||
<%= render AppInfoComponent.new(
|
||||
name: "Phanpy",
|
||||
description: " A slick, feature-rich Web app for mobile and desktop",
|
||||
icon_path: "/img/logos/icon_phanpy.svg",
|
||||
links: [
|
||||
["Launch", "https://phanpy.social"],
|
||||
["GitHub", "https://github.com/cheeaun/phanpy"]
|
||||
]
|
||||
) %>
|
||||
<%= render AppInfoComponent.new(
|
||||
@@ -150,6 +160,15 @@
|
||||
["Google Play", "https://play.google.com/store/apps/details?id=org.joinmastodon.android.sk"]
|
||||
]
|
||||
) %>
|
||||
<%= render AppInfoComponent.new(
|
||||
name: "Phanpy",
|
||||
description: " A slick, feature-rich Web app for mobile and desktop",
|
||||
icon_path: "/img/logos/icon_phanpy.svg",
|
||||
links: [
|
||||
["Launch", "https://phanpy.social"],
|
||||
["GitHub", "https://github.com/cheeaun/phanpy"]
|
||||
]
|
||||
) %>
|
||||
</div>
|
||||
<div class="hidden grid grid-cols-1 gap-6" data-tabs-target="panel">
|
||||
<%= render AppInfoComponent.new(
|
||||
@@ -180,6 +199,15 @@
|
||||
["App Store", "https://apps.apple.com/app/mammoth-for-mastodon/id1667573899"]
|
||||
]
|
||||
) %>
|
||||
<%= render AppInfoComponent.new(
|
||||
name: "Phanpy",
|
||||
description: " A slick, feature-rich Web app for mobile and desktop",
|
||||
icon_path: "/img/logos/icon_phanpy.svg",
|
||||
links: [
|
||||
["Launch", "https://phanpy.social"],
|
||||
["GitHub", "https://github.com/cheeaun/phanpy"]
|
||||
]
|
||||
) %>
|
||||
</div>
|
||||
<div class="hidden grid grid-cols-1 gap-6" data-tabs-target="panel">
|
||||
<%= render AppInfoComponent.new(
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
:queues:
|
||||
- default
|
||||
- mailers
|
||||
- remotestorage
|
||||
|
||||
@@ -19,18 +19,6 @@ namespace :ldap do
|
||||
}, true
|
||||
end
|
||||
|
||||
# TODO
|
||||
desc "Add application account to directory"
|
||||
task add_application_account: :environment do |t, args|
|
||||
# Add uid=service,ou=kosmos.org,cn=applications,dc=kosmos,dc=org with userPassword
|
||||
end
|
||||
|
||||
# TODO
|
||||
desc "Add application ACI/permissions for OU, i.e. read/search users"
|
||||
task add_application_account: :environment do |t, args|
|
||||
# (target="ldap:///cn=*,ou=#{ou},cn=users,#{ldap_suffix}")(targetattr="cn || sn || uid || mail || userPassword || nsRole || objectClass") (version 3.0; acl "service-#{ou.gsub(".", "-")}-read-search"; allow (read,search) userdn="ldap:///uid=service,ou=#{ou},cn=applications,#{ldap_suffix}";)
|
||||
end
|
||||
|
||||
desc "Add custom attributes to schema"
|
||||
task add_custom_attributes: :environment do |t, args|
|
||||
%w[ admin service_enabled nostr_key ].each do |name|
|
||||
|
||||
67
public/img/logos/icon_phanpy.svg
Normal file
67
public/img/logos/icon_phanpy.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="54"
|
||||
height="54"
|
||||
viewBox="0 0 54 54"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
|
||||
id="svg4"
|
||||
sodipodi:docname="icon_phanpy.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:serif="http://www.serif.com/"><defs
|
||||
id="defs4" /><sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="16.359375"
|
||||
inkscape:cx="26.192932"
|
||||
inkscape:cy="24.542502"
|
||||
inkscape:window-width="2160"
|
||||
inkscape:window-height="1281"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<rect
|
||||
id="Logo-simple"
|
||||
serif:id="Logo simple"
|
||||
x="0"
|
||||
y="0"
|
||||
width="63.993999"
|
||||
height="63.993999"
|
||||
style="fill:none" />
|
||||
<g
|
||||
id="Logo-simple1"
|
||||
serif:id="Logo simple"
|
||||
transform="translate(-5.123639,-4.9968626)">
|
||||
<g
|
||||
id="g4">
|
||||
<path
|
||||
d="m 37.774,11.471 c 14.639,3.752 19.034,16.557 15.889,31.304 -0.696,3.261 -2.563,6.661 -6.356,8.693 -3.204,1.717 -8.07,2.537 -15.338,0.55 0,0 -9.634,-2.404 -9.634,-2.404 C 11.651,46.992 8.378,38.733 10.027,31.823 13.654,16.622 25.57,8.343 37.774,11.471 Z"
|
||||
style="fill:#a4bff7"
|
||||
id="path1" />
|
||||
<path
|
||||
d="m 36.76,15.429 c 12.289,3.15 15.547,14.114 12.907,26.493 -0.947,4.44 -4.937,9.365 -16.664,6.143 L 23.319,45.648 C 15.465,43.725 12.789,37.848 14.001,32.771 17.017,20.132 26.612,12.828 36.76,15.429 Z"
|
||||
style="fill:#d8e7fe"
|
||||
id="path2" />
|
||||
<path
|
||||
d="m 27.471,24.991 c -1.457,-0.698 -7.229,3.213 -7.663,8.926 -0.182,2.39 4.55,3.237 5.071,-0.169 0.725,-4.743 3.715,-8.218 2.592,-8.757 z"
|
||||
style="fill:#6081e6"
|
||||
id="path3" />
|
||||
<path
|
||||
d="m 38.217,26.996 c -2.083,0.327 -0.382,5.901 -0.595,10.727 -0.123,2.8 4.388,3.464 4.703,2.011 1.098,-5.073 -2.066,-13.058 -4.108,-12.738 z"
|
||||
style="fill:#6081e6"
|
||||
id="path4" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -1,4 +0,0 @@
|
||||
dn: ou=kosmos.org,cn=users,dc=kosmos,dc=org
|
||||
changetype: modify
|
||||
add: aci
|
||||
aci: (target="ldap:///cn=*,ou=kosmos.org,cn=users,dc=kosmos,dc=org")(targetattr="cn || sn || uid || mail || userPassword || serviceEnabled || displayName || jpegPhoto || nsRole || objectClass") (version 3.0; acl "service-kosmos-read-search"; allow (read,search) userdn="ldap:///uid=service,ou=kosmos.org,cn=applications,dc=kosmos,dc=org";)
|
||||
@@ -1,4 +0,0 @@
|
||||
dn: ou=kosmos.org,cn=users,dc=kosmos,dc=org
|
||||
changetype: modify
|
||||
delete: aci
|
||||
aci: (target="ldap:///cn=*,ou=kosmos.org,cn=users,dc=kosmos,dc=org")(targetattr="cn || sn || uid || mail || userPassword || nsRole || objectClass") (version 3.0; acl "service-kosmos-read-search"; allow (read,search) userdn="ldap:///uid=service,ou=kosmos.org,cn=applications,dc=kosmos,dc=org";)
|
||||
@@ -3,12 +3,24 @@ require 'rails_helper'
|
||||
RSpec.describe CreateLdapUserJob, type: :job do
|
||||
let(:ldap_client_mock) { instance_double(Net::LDAP) }
|
||||
|
||||
subject(:job) {
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:ldap_client).and_return(ldap_client_mock)
|
||||
end
|
||||
|
||||
subject(:job) {
|
||||
described_class.perform_later(
|
||||
'halfinney', 'kosmos.org', 'halfinney@example.com',
|
||||
'remember-remember-the-5th-of-november'
|
||||
username: 'halfinney', domain: 'kosmos.org',
|
||||
email: 'halfinney@example.com',
|
||||
hashed_pw: 'remember-remember-the-5th-of-november'
|
||||
)
|
||||
}
|
||||
|
||||
subject(:job_for_preconfirmed_account) {
|
||||
described_class.perform_later(
|
||||
username: 'halfinney', domain: 'kosmos.org',
|
||||
email: 'halfinney@example.com',
|
||||
hashed_pw: 'remember-remember-the-5th-of-november',
|
||||
confirmed: true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,6 +42,26 @@ RSpec.describe CreateLdapUserJob, type: :job do
|
||||
)
|
||||
end
|
||||
|
||||
it "adds default services for pre-confirmed accounts" do
|
||||
allow(ldap_client_mock).to receive(:add) # spy on mock
|
||||
allow(Setting).to receive(:default_services).and_return(["xmpp", "discourse"])
|
||||
|
||||
perform_enqueued_jobs { job_for_preconfirmed_account }
|
||||
|
||||
expect(ldap_client_mock).to have_received(:add).with(
|
||||
dn: "cn=halfinney,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
|
||||
attributes: {
|
||||
objectclass: ["top", "account", "person", "extensibleObject"],
|
||||
cn: "halfinney",
|
||||
sn: "halfinney",
|
||||
uid: "halfinney",
|
||||
mail: "halfinney@example.com",
|
||||
serviceEnabled: ["xmpp", "discourse"],
|
||||
userPassword: "remember-remember-the-5th-of-november"
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
after do
|
||||
clear_enqueued_jobs
|
||||
clear_performed_jobs
|
||||
|
||||
@@ -16,6 +16,10 @@ RSpec.describe User, type: :model do
|
||||
let(:user) { build :user, cn: "jimmy", ou: "kosmos.org" }
|
||||
|
||||
context "Mastodon service not configured" do
|
||||
before do
|
||||
Setting.mastodon_enabled = false
|
||||
end
|
||||
|
||||
it "returns nil" do
|
||||
expect(user.mastodon_address).to be_nil
|
||||
end
|
||||
@@ -41,6 +45,14 @@ RSpec.describe User, type: :model do
|
||||
expect(user.mastodon_address).to eq("jimmy@kosmos.social")
|
||||
end
|
||||
end
|
||||
|
||||
describe "username contains hyphen/dash" do
|
||||
let(:jammy) { build :user, cn: "jammy-jellyfish", ou: "kosmos.org" }
|
||||
|
||||
it "returns the user address" do
|
||||
expect(jammy.mastodon_address).to eq("jammy_jellyfish@kosmos.org")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,6 +84,25 @@ RSpec.describe User, type: :model do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#service_enabled?" do
|
||||
before do
|
||||
allow(user).to receive(:ldap_entry).and_return({
|
||||
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
||||
services_enabled: ["gitea", "xmpp"]
|
||||
})
|
||||
end
|
||||
|
||||
it "returns true or false" do
|
||||
expect(user.service_enabled?("gitea")).to be(true)
|
||||
expect(user.service_enabled?("email")).to be(false)
|
||||
end
|
||||
|
||||
it "returns false when service is not enabled" do
|
||||
expect(user.service_enabled?(:gitea)).to be(true)
|
||||
expect(user.service_enabled?(:email)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#enable_service" do
|
||||
before do
|
||||
allow(user).to receive(:ldap_entry).and_return({
|
||||
@@ -147,7 +178,7 @@ RSpec.describe User, type: :model do
|
||||
after { clear_enqueued_jobs }
|
||||
|
||||
it "enables default services" do
|
||||
expect(user).to receive(:enable_service).with(%w[ discourse gitea mediawiki xmpp ])
|
||||
expect(user).to receive(:enable_service).with(%w[ discourse gitea mastodon mediawiki xmpp ])
|
||||
user.send :devise_after_confirmation
|
||||
end
|
||||
|
||||
|
||||
@@ -1,13 +1,87 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe "WebFinger", type: :request do
|
||||
describe "remoteStorage link relation" do
|
||||
context "user exists" do
|
||||
before do
|
||||
create :user, cn: 'tony', ou: 'kosmos.org'
|
||||
describe "User does not exist" do
|
||||
it "returns a 404 status" do
|
||||
get "/.well-known/webfinger?resource=acct%3Ajane.doe%40kosmos.org"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context "User exists" do
|
||||
let(:user) { create :user, cn: 'tony', ou: 'kosmos.org' }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(User).to receive(:ldap_entry).and_return({
|
||||
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
||||
services_enabled: ["mastodon", "remotestorage"]
|
||||
})
|
||||
end
|
||||
|
||||
describe "Mastodon entries" do
|
||||
context "Mastodon available" do
|
||||
it "includes the Mastodon aliases and links for the user" do
|
||||
get "/.well-known/webfinger?resource=acct%3Atony%40kosmos.org"
|
||||
expect(response).to have_http_status(:ok)
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
|
||||
expect(res["aliases"]).to include("http://example.social/@tony")
|
||||
expect(res["aliases"]).to include("http://example.social/users/tony")
|
||||
|
||||
profile_link = res["links"].find{|l| l["rel"] == "http://webfinger.net/rel/profile-page"}
|
||||
self_link = res["links"].find{|l| l["rel"] == "self"}
|
||||
ostatus_link = res["links"].find{|l| l["rel"] == "http://ostatus.org/schema/1.0/subscribe"}
|
||||
expect(profile_link["type"]).to eql("text/html")
|
||||
expect(profile_link["href"]).to eql("http://example.social/@tony")
|
||||
expect(self_link["type"]).to eql("application/activity+json")
|
||||
expect(self_link["href"]).to eql("http://example.social/users/tony")
|
||||
expect(ostatus_link["template"]).to eql("http://example.social/authorize_interaction?uri={uri}")
|
||||
end
|
||||
end
|
||||
|
||||
context "remoteStorage enabled globally" do
|
||||
context "Mastodon not enabled for user" do
|
||||
before do
|
||||
allow_any_instance_of(User).to receive(:ldap_entry).and_return({
|
||||
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
||||
services_enabled: ["xmpp"]
|
||||
})
|
||||
end
|
||||
|
||||
it "does not include Mastodon aliases or links" do
|
||||
get "/.well-known/webfinger?resource=acct%3Atony%40kosmos.org"
|
||||
expect(response).to have_http_status(:ok)
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["aliases"]).not_to include("http://example.social/@tony")
|
||||
expect(res["aliases"]).not_to include("http://example.social/users/tony")
|
||||
expect(res["links"].find{|l| l["rel"] == "http://webfinger.net/rel/profile-page"}).to be(nil)
|
||||
expect(res["links"].find{|l| l["rel"] == "self"}).to be(nil)
|
||||
expect(res["links"].find{|l| l["rel"] == "http://ostatus.org/schema/1.0/subscribe"}).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "Mastodon not available" do
|
||||
before do
|
||||
Setting.mastodon_enabled = false
|
||||
end
|
||||
|
||||
it "does not include Mastodon aliases or links" do
|
||||
get "/.well-known/webfinger?resource=acct%3Atony%40kosmos.org"
|
||||
expect(response).to have_http_status(:ok)
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["aliases"]).not_to include("http://example.social/@tony")
|
||||
expect(res["aliases"]).not_to include("http://example.social/users/tony")
|
||||
expect(res["links"].find{|l| l["rel"] == "http://webfinger.net/rel/profile-page"}).to be(nil)
|
||||
expect(res["links"].find{|l| l["rel"] == "self"}).to be(nil)
|
||||
expect(res["links"].find{|l| l["rel"] == "http://ostatus.org/schema/1.0/subscribe"}).to be(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "remoteStorage entries" do
|
||||
context "remoteStorage available" do
|
||||
it "includes the remoteStorage link for the user" do
|
||||
get "/.well-known/webfinger?resource=acct%3Atony%40kosmos.org"
|
||||
expect(response).to have_http_status(:ok)
|
||||
@@ -22,6 +96,25 @@ RSpec.describe "WebFinger", type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
context "remoteStorage not enabled for user" do
|
||||
before do
|
||||
allow_any_instance_of(User).to receive(:ldap_entry).and_return({
|
||||
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
||||
services_enabled: ["xmpp"]
|
||||
})
|
||||
end
|
||||
|
||||
it "does not include the remoteStorage link" do
|
||||
get "/.well-known/webfinger?resource=acct%3Atony%40kosmos.org"
|
||||
expect(response).to have_http_status(:ok)
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
rs_link = res["links"].find {|l| l["rel"] == "http://tools.ietf.org/id/draft-dejong-remotestorage"}
|
||||
|
||||
expect(rs_link).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "remoteStorage not available" do
|
||||
before do
|
||||
Setting.remotestorage_enabled = false
|
||||
@@ -38,12 +131,5 @@ RSpec.describe "WebFinger", type: :request do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "user does not exist" do
|
||||
it "does return a 404 status" do
|
||||
get "/.well-known/webfinger?resource=acct%3Ajane.doe%40kosmos.org"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,11 +53,32 @@ RSpec.describe CreateAccount, type: :model do
|
||||
|
||||
expect(enqueued_jobs.size).to eq(1)
|
||||
|
||||
args = enqueued_jobs.first['arguments']
|
||||
expect(args[0]).to eq('halfinney')
|
||||
expect(args[1]).to eq('kosmos.org')
|
||||
expect(args[2]).to eq('halfinney@example.com')
|
||||
expect(args[3]).to match(/^{SSHA512}.{171}=/)
|
||||
args = enqueued_jobs.first['arguments'][0]
|
||||
expect(args["username"]).to eq('halfinney')
|
||||
expect(args["domain"]).to eq('kosmos.org')
|
||||
expect(args["email"]).to eq('halfinney@example.com')
|
||||
expect(args["hashed_pw"]).to match(/^{SSHA512}.{171}=/)
|
||||
end
|
||||
|
||||
after do
|
||||
clear_enqueued_jobs
|
||||
end
|
||||
end
|
||||
|
||||
describe "#add_ldap_document for pre-confirmed account" do
|
||||
include ActiveJob::TestHelper
|
||||
|
||||
let(:service) { CreateAccount.new(account: {
|
||||
username: 'halfinney',
|
||||
email: 'halfinney@example.com',
|
||||
password: 'remember-remember-the-5th-of-november',
|
||||
confirmed: true
|
||||
})}
|
||||
|
||||
it "enqueues a job to create the LDAP user document" do
|
||||
service.send(:add_ldap_document)
|
||||
args = enqueued_jobs.first['arguments'][0]
|
||||
expect(args["confirmed"]).to be(true)
|
||||
end
|
||||
|
||||
after do
|
||||
|
||||
Reference in New Issue
Block a user