Modifications suite à mise à jour loomio
This commit is contained in:
parent
83b8d78829
commit
8074b2b516
10
README.md
10
README.md
|
@ -21,7 +21,6 @@ docker_loomio_smtp_server: smtp.example.com
|
|||
docker_loomio_db_name: loomio
|
||||
docker_loomio_db_user: loomiodbuser
|
||||
docker_loomio_db_password: mdp_de_loomiodbuser
|
||||
docker_loomio_secret_key_base: ici_le_secret_key_base
|
||||
docker_loomio_devise_secret: ici_le_devise_secret
|
||||
docker_loomio_secret_cookie_token: ici_le_secret_cookie_token
|
||||
```
|
||||
|
@ -38,16 +37,21 @@ docker_loomio_secret_cookie_token: ici_le_secret_cookie_token
|
|||
| docker_loomio_db_name | | Nom de la base de données postgres pour loomio |
|
||||
| docker_loomio_db_user | | Nom du user postgres propriétaire de la base de données |
|
||||
| docker_loomio_db_password | | Mot du passe du user postgres |
|
||||
| docker_loomio_secret_key_base | | s'obtient avec docker-compose run app rake secret |
|
||||
| docker_loomio_devise_secret | | s'obtient avec openssl rand -base64 48 |
|
||||
| docker_loomio_secret_cookie_token | | s'obtient avec openssl rand -base64 48 |
|
||||
| docker_loomio_features_disable_create_user | false | Si true, désactive la possibilité de créer un utilisateur sans invitation |
|
||||
| docker_loomio_features_disable_create_group | false | Si true, désactive la possibilité pour les utilisateurs de créer des groupes |
|
||||
|
||||
|
||||
## Point d'attention
|
||||
|
||||
Le fonctionnement de loomio nécessite deux urls dont il faut tenir compte (DNS notamment) :
|
||||
* une décrite dans docker_loomio_fqdn
|
||||
* une seconde qui correspond à channels.{{ docker_loomio_fqdn }}
|
||||
|
||||
## Première installation dans loomio
|
||||
|
||||
A la première exécution du playbook, la base de données est initialisée et des valeurs sont proposées pour docker_loomio_secret_key_base, docker_loomio_devise_secret et docker_loomio_secret_cookie_token qu'il suffit de reporter dans les variables ansible. Relancer ensuite le playbook après avoir renseigné ces variables.
|
||||
A la première exécution du playbook, la base de données est initialisée et des valeurs sont proposées pour docker_loomio_devise_secret et docker_loomio_secret_cookie_token qu'il suffit de reporter dans les variables ansible. Relancer ensuite le playbook après avoir renseigné ces variables.
|
||||
|
||||
Se connecter à loomio et enregistrer un premier utilisateur, pui promouvoir celui-ci en administrateur de l'instance loomio par :
|
||||
```
|
||||
|
|
|
@ -9,13 +9,14 @@
|
|||
state: directory
|
||||
register: _datadir
|
||||
|
||||
- name: prepare docker-compose.yml
|
||||
- name: prepare docker-compose files
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: /opt/{{ docker_loomio_service_id }}/
|
||||
with_items:
|
||||
- docker-compose.yml
|
||||
- env
|
||||
- libretic_patch_group_service.rb
|
||||
notify: docker-compose-up
|
||||
|
||||
- name: prepare loomio cron tasks
|
||||
|
@ -28,8 +29,6 @@
|
|||
shell: |
|
||||
docker-compose up -d db
|
||||
docker-compose run app rake db:setup
|
||||
echo "You can use secret below into docker_loomio_secret_key_base"
|
||||
docker-compose run app rake secret
|
||||
echo "You can use secret below into docker_loomio_devise_secret"
|
||||
openssl rand -base64 48
|
||||
echo "You can use secret below into docker_loomio_secret_cookie_token"
|
||||
|
|
|
@ -5,7 +5,7 @@ version: '3.1'
|
|||
services:
|
||||
app:
|
||||
image: loomio/loomio:{{ docker_loomio_version }}
|
||||
restart: unless-stopped
|
||||
restart: always
|
||||
expose:
|
||||
- 3000
|
||||
env_file: ./env
|
||||
|
@ -16,6 +16,7 @@ services:
|
|||
- {{ docker_loomio_data_dir }}/{{ docker_loomio_service_id }}/plugins:/loomio/plugins/docker
|
||||
- {{ docker_loomio_data_dir }}/{{ docker_loomio_service_id }}/import:/import
|
||||
- {{ docker_loomio_data_dir }}/{{ docker_loomio_service_id }}/tmp:/loomio/tmp
|
||||
- ./libretic_patch_group_service.rb:/loomio/app/services/group_service.rb
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
|
@ -50,7 +51,7 @@ services:
|
|||
|
||||
channels:
|
||||
image: loomio/loomio_channel_server
|
||||
restart: unless-stopped
|
||||
restart: always
|
||||
env_file: ./env
|
||||
depends_on:
|
||||
- redis
|
||||
|
@ -58,7 +59,7 @@ services:
|
|||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik"
|
||||
- "traefik.http.routers.{{ docker_loomio_service_id }}-channels.entrypoints=web"
|
||||
- "traefik.http.routers.{{ docker_loomio_service_id }}-channels.rule=Host(`{{ docker_loomio_fqdn }}`) && PathPrefix(`/socket.io/`)"
|
||||
- "traefik.http.routers.{{ docker_loomio_service_id }}-channels.rule=Host(`channels.{{ docker_loomio_fqdn }}`)"
|
||||
- "traefik.http.services.{{ docker_loomio_service_id }}-channels.loadbalancer.server.port=5000"
|
||||
networks:
|
||||
- loomio
|
||||
|
@ -66,7 +67,7 @@ services:
|
|||
|
||||
db:
|
||||
image: postgres:14
|
||||
restart: unless-stopped
|
||||
restart: always
|
||||
networks:
|
||||
- loomio
|
||||
healthcheck:
|
||||
|
@ -82,7 +83,7 @@ services:
|
|||
|
||||
redis:
|
||||
image: redis:5.0
|
||||
restart: unless-stopped
|
||||
restart: always
|
||||
networks:
|
||||
- loomio
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ SITE_NAME={{ docker_loomio_name }}
|
|||
REPLY_HOSTNAME={{ docker_loomio_reply_to }}
|
||||
|
||||
# channels
|
||||
CHANNELS_URI=wss://{{ docker_loomio_fqdn }}
|
||||
CHANNELS_URI=wss://channels.{{ docker_loomio_fqdn }}
|
||||
|
||||
# uncomment this if you want a default subdomain of www (eg: www.loomio.org)
|
||||
# DEFAULT_SUBDOMAIN=www
|
||||
|
@ -30,6 +30,7 @@ NOTIFICATIONS_EMAIL_ADDRESS={{ docker_loomio_reply_to }}
|
|||
# helper bot is the account which welcomes people to their groups.
|
||||
HELPER_BOT_EMAIL={{ docker_loomio_reply_to }}
|
||||
RAILS_ENV=production
|
||||
#RAILS_LOG_LEVEL=debug
|
||||
|
||||
# Number of webserver processes and threads
|
||||
# threads are per worker. See https://github.com/puma/puma
|
||||
|
@ -148,6 +149,5 @@ FEATURES_DISABLE_CREATE_GROUP=1
|
|||
# tell clients to reload when the server is upgraded
|
||||
LOOMIO_SYSTEM_RELOAD=1
|
||||
|
||||
SECRET_KEY_BASE={{ docker_loomio_secret_key_base }}
|
||||
DEVISE_SECRET={{ docker_loomio_devise_secret }}
|
||||
SECRET_COOKIE_TOKEN={{ docker_loomio_secret_cookie_token }}
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
module GroupService
|
||||
def self.remote_cover_photo
|
||||
# id like to use unsplash api but need to work out how to meet their attribution requirements
|
||||
# if !Rails.env.test?
|
||||
if false
|
||||
[
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/001/original/open-uri20150904-3-16e2exd?1441337903",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/002/original/open-uri20150904-3-rdqbrq?1441337903",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/003/original/open-uri20150904-3-1oppl5v?1441337903",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/004/original/open-uri20150904-3-pk5rt7?1441337903",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/005/original/open-uri20150904-3-llrp8p?1441337904",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/006/original/open-uri20150904-3-12f1pb7?1441337904",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/007/original/open-uri20150904-3-mnvdi7?1441337904",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/008/original/open-uri20150904-3-ug7qk8?1441337904",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/009/original/open-uri20150904-3-kxuccv?1441337904",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/010/original/open-uri20150904-3-1v5vy0t?1441337904",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/011/original/open-uri20150904-3-nk5ttf?1441337905",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/012/original/open-uri20150904-3-12mh2l4?1441337905",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/013/original/open-uri20150904-3-1rh3y2o?1441337905",
|
||||
"https://loomio-uploads.s3.amazonaws.com/default_group_covers/cover_photos/000/000/014/original/open-uri20150904-3-18nwpr9?1441337905"
|
||||
].sample
|
||||
else
|
||||
[ Rails.root.join('public/theme/default_group_cover.png') ].sample
|
||||
end
|
||||
end
|
||||
|
||||
def self.invite(group:, params:, actor:)
|
||||
group_ids = if params[:invited_group_ids]
|
||||
Array(params[:invited_group_ids])
|
||||
else
|
||||
Array(group.id)
|
||||
end
|
||||
|
||||
groups = Group.where(id: group_ids).each { |g| actor.ability.authorize!(:add_members, g) }
|
||||
|
||||
users = UserInviter.where_or_create!(actor: actor,
|
||||
model: group,
|
||||
emails: params[:recipient_emails],
|
||||
user_ids: params[:recipient_user_ids])
|
||||
|
||||
groups.each do |g|
|
||||
memberships = users.map do |user|
|
||||
Membership.new(inviter: actor, user: user, group: g, volume: 2)
|
||||
end
|
||||
|
||||
Membership.import(memberships, on_duplicate_key_ignore: true)
|
||||
|
||||
# mark as accepted all invitiations to people who are already part of the org.
|
||||
if g.parent
|
||||
parent_members = g.parent.accepted_members.where(id: users.verified.pluck(:id))
|
||||
Membership.pending.where(group_id: g.id,
|
||||
user_id: parent_members.pluck(:id)).update_all(accepted_at: Time.now)
|
||||
end
|
||||
|
||||
g.update_pending_memberships_count
|
||||
g.update_memberships_count
|
||||
end
|
||||
|
||||
Events::MembershipCreated.publish!(
|
||||
group: group,
|
||||
actor: actor,
|
||||
recipient_user_ids: users.pluck(:id),
|
||||
recipient_message: params[:recipient_message])
|
||||
|
||||
# EventBus.broadcast('group_invite', group, actor, all_memberships.size)
|
||||
Membership.not_archived.where(group_id: group.id, user_id: users.pluck(:id))
|
||||
|
||||
end
|
||||
|
||||
def self.create(group:, actor: )
|
||||
actor.ability.authorize! :create, group
|
||||
|
||||
return false unless group.valid?
|
||||
|
||||
group.is_referral = actor.groups.size > 0
|
||||
|
||||
if group.is_parent?
|
||||
url = remote_cover_photo
|
||||
group.cover_photo.attach(io: URI.open(url), filename: File.basename(url))
|
||||
group.creator = actor if actor.is_logged_in?
|
||||
|
||||
if template_group = Group.find_by(handle: 'trial-group-template')
|
||||
cloner = RecordCloner.new(recorded_at: template_group.discussions.last.updated_at)
|
||||
cloner.clone_trial_content_into_group(group, actor)
|
||||
end
|
||||
group.subscription = Subscription.new
|
||||
end
|
||||
|
||||
group.save!
|
||||
group.add_admin!(actor)
|
||||
|
||||
EventBus.broadcast('group_create', group, actor)
|
||||
end
|
||||
|
||||
def self.update(group:, params:, actor:)
|
||||
actor.ability.authorize! :update, group
|
||||
|
||||
group.assign_attributes_and_files(params)
|
||||
group.group_privacy = params[:group_privacy] if params.has_key?(:group_privacy)
|
||||
privacy_change = PrivacyChange.new(group)
|
||||
|
||||
return false unless group.valid?
|
||||
group.save!
|
||||
privacy_change.commit!
|
||||
|
||||
EventBus.broadcast('group_update', group, params, actor)
|
||||
end
|
||||
|
||||
def self.destroy(group:, actor:)
|
||||
actor.ability.authorize! :destroy, group
|
||||
|
||||
group.admins.each do |admin|
|
||||
GroupMailer.delay.destroy_warning(group.id, admin.id, actor.id)
|
||||
end
|
||||
|
||||
group.archive!
|
||||
|
||||
DestroyGroupWorker.perform_in(2.weeks, group.id)
|
||||
EventBus.broadcast('group_destroy', group, actor)
|
||||
end
|
||||
|
||||
def self.destroy_without_warning!(group_id)
|
||||
Group.find(group_id).archive!
|
||||
DestroyGroupWorker.perform_async(group_id)
|
||||
end
|
||||
|
||||
def self.move(group:, parent:, actor:)
|
||||
actor.ability.authorize! :move, group
|
||||
group.update(handle: "#{parent.handle}-#{group.handle}") if group.handle?
|
||||
group.update(parent: parent, subscription_id: nil)
|
||||
EventBus.broadcast('group_move', group, parent, actor)
|
||||
end
|
||||
|
||||
def self.export(group: , actor: )
|
||||
actor.ability.authorize! :show, group
|
||||
group_ids = actor.groups.where(id: group.all_groups).pluck(:id)
|
||||
GroupExportWorker.perform_async(group_ids, group.name, actor.id)
|
||||
end
|
||||
|
||||
def self.merge(source:, target:, actor:)
|
||||
actor.ability.authorize! :merge, source
|
||||
actor.ability.authorize! :merge, target
|
||||
|
||||
Group.transaction do
|
||||
source.subgroups.update_all(parent_id: target.id)
|
||||
source.discussions.update_all(group_id: target.id)
|
||||
source.polls.update_all(group_id: target.id)
|
||||
source.membership_requests.update_all(group_id: target.id)
|
||||
source.group_identities.update_all(group_id: target.id)
|
||||
source.memberships.where.not(user_id: target.member_ids).update_all(group_id: target.id)
|
||||
source.destroy
|
||||
end
|
||||
end
|
||||
|
||||
def self.suggest_handle(name:, parent_handle:)
|
||||
attempt = 0
|
||||
while(Group.where(handle: generate_handle(name, parent_handle, attempt)).exists?) do
|
||||
attempt += 1
|
||||
end
|
||||
generate_handle(name, parent_handle, attempt)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.generate_handle(name, parent_handle, attempt)
|
||||
[parent_handle,
|
||||
name,
|
||||
(attempt == 0) ? nil : attempt].compact.map{|t| t.to_s.strip.parameterize}.join('-')
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue