56 Commits

Author SHA1 Message Date
Klaus Zanders 50104b4900 Ensure department check also runs when adding users to a Group via AddUsersService 2026-04-16 17:24:28 +02:00
Klaus Zanders 3f83a921b4 Also add children groups as members 2026-03-18 12:09:00 +01:00
Klaus Zanders 9728990fdf Implement membership propagation for memberships 2026-03-16 15:42:31 +01:00
Jan Sandbrink 706fb7c645 Replace user_ids param with (add|remove|replace)_user_ids
Previously it was always necessary to provide a full list of users when calling the service.
Now it's also possible to provide a delta that should be achieved.

This allows to simplify calls to the service, when only the delta is known (e.g. "add this user").
It also makes those calls safer, since the internals of the Groups::UpdateService are already locked
through an advisory lock (via BaseContracted), thus concurrent changes to group memberships are serialized
properly inside the service. However, previous implementations would have read the current members of a group
outside of the service scope, where race conditions could have occured.
2025-07-31 09:32:26 +02:00
Jan Sandbrink 0b87e7543f Freeze string literals in specs
Rolling out frozen string literals further by freezing all
string literals in core specs.
2025-05-05 09:29:55 +02:00
Ivan Kuchin 4911b8a149 remove years from copyrights (except for COPYRIGHT file) 2024-07-31 15:02:49 +02:00
Christophe Bliard 7d06e26e7b Fix flickering cleanup_inherited_roles_service_integration_spec test
The subject test was `Member.find_by(principal: users.last).roles`. As
there are 3 different `Member` records having the same principal, it
could return any of them. Most of the time it would always be the first
one, which is a project role membership and satisfies the test
conditions, but occasionnally, it would be the global role membership or
the work package role membership and the test would fail.

Using `Member.where(principal: users.last).flat_map(&:roles)` and
testing for all roles fixes the test flakiness.

Also changed some wording here and there to make the test easier to
understand.
2024-07-09 09:55:27 +02:00
ulferts 3b2121f733 Revert "Merge remote-tracking branch 'origin/release/13.4' into dev"
This reverts commit 40b2bbeb09, reversing
changes made to b4c6cb17cc.
2024-03-21 11:31:17 +01:00
Ivan Kuchin 7787e457a3 Revert "Merge branch 'dev' into release/13.4"
This reverts commit a901541269, reversing
changes made to e573ca00b7.
2024-03-20 20:19:08 +01:00
Ivan Kuchin 9e4934cd0a change quotes using rubocop --only Style/StringLiterals,Style/QuotedSymbols -a 2024-03-20 18:05:22 +01:00
Christophe Bliard c795874f7f Update copyright year for 2024
command used: `rg -l 'Copyright \(C\) 2012-202\d the OpenProject' | xargs -n 100 sed -i -r 's/Copyright \(C\) 2012-202. the OpenProject/Copyright (C) 2012-2024 the OpenProject/'`
2024-01-02 16:23:54 +01:00
Aaron Contreras 7a72381759 Performance: Improve performance of update_roles_service_integration_spec
We're spending over 50% of the time spent in factories. By leveraging the
`shared_let` strategy we can chop this down significantly to something more
reasonable.

Performance was improved by 50% as well as with a 50% reduction in time spent in
factories.

** Before **
Finished in 4.82 seconds (files took 9.09 seconds to load)
46 examples, 0 failures

Randomized with seed 3124

[TEST PROF INFO] Time spent in factories: 00:04.020 (57.97% of total time)
[TEST PROF INFO] Factories usage

 Total: 499
 Total top-level: 366
 Total time: 00:04.020 (out of 00:11.324)
 Total uniq factories: 9

   total   top-level     total time      time per call      top-level time               name

     133           0        0.2047s            0.0015s             0.0000s notification_setting
      88          88        0.9106s            0.0103s             0.9106s               user
      79          79        0.2084s            0.0026s             0.2084s       project_role
      50          50        0.6100s            0.0122s             0.6100s              group
      45          45        0.3730s            0.0083s             0.3730s              admin
      42          42        0.1811s            0.0043s             0.1811s             member
      38          38        1.6674s            0.0439s             1.6674s            project
      16          16        0.0382s            0.0024s             0.0382s        global_role
       8           8        0.0321s            0.0040s             0.0321s      global_member

** After **

Finished in 2.15 seconds (files took 8.89 seconds to load)
46 examples, 0 failures

Randomized with seed 44002

[TEST PROF INFO] Time spent in factories: 00:01.168 (27.67% of total time)
[TEST PROF INFO] Factories usage

 Total: 121
 Total top-level: 117
 Total time: 00:01.168 (out of 00:08.508)
 Total uniq factories: 9

   total   top-level     total time      time per call      top-level time               name

      50          50        0.5710s            0.0114s             0.5710s              group
      42          42        0.1891s            0.0045s             0.1891s             member
       9           9        0.0561s            0.0062s             0.0561s       project_role
       8           8        0.0338s            0.0042s             0.0338s      global_member
       4           0        0.0159s            0.0040s             0.0000s notification_setting
       3           3        0.0233s            0.0078s             0.0233s               user
       3           3        0.0101s            0.0034s             0.0101s        global_role
       1           1        0.0376s            0.0376s             0.0376s              admin
       1           1        0.2474s            0.2474s             0.2474s            project
2023-10-16 09:47:01 -05:00
Aaron Contreras 7e810fd90f Lint: Address cop about usage of match_array
* Replaces `match_array` with `contain_exactly` where applicable.
2023-10-16 09:47:01 -05:00
Aaron Contreras 5ad278214e Extend cleanup inherited roles integration spec to cover work package roles 2023-10-16 09:46:59 -05:00
Aaron Contreras cbeee85b3c Performance: Improve performance of integration spec
There is no case of factory cascading as demonstrated by the test-prof output
in the below ** BEFORE ** section. However, we're creating a lot of factories
and spending ~40% of the time in factories.

By using `shared_let`, we can reduce the number of factories being created
and speed up the test with the same behavior as it currently has.

Execution time was cut to < 1 second, meaning the spec file is now 2.6x faster.

** BEFORE **

Finished in 2.47 seconds (files took 9.5 seconds to load)
17 examples, 0 failures

Randomized with seed 8911

[TEST PROF INFO] Time spent in factories: 00:01.863 (40.63% of total time)
[TEST PROF INFO] Factories usage

 Total: 210
 Total top-level: 160
 Total time: 00:01.863 (out of 00:08.721)
 Total uniq factories: 9

   total   top-level     total time      time per call      top-level time               name

      50           0        0.0872s            0.0017s             0.0000s notification_setting
      34          34        0.4331s            0.0127s             0.4331s               user
      21          21        0.0600s            0.0029s             0.0600s               role
      21          21        0.0551s            0.0026s             0.0551s        global_role
      17          17        0.2831s            0.0167s             0.2831s              group
      17          17        0.0770s            0.0045s             0.0770s             member
      17          17        0.0518s            0.0030s             0.0518s      global_member
      17          17        0.7791s            0.0458s             0.7791s            project
      16          16        0.1244s            0.0078s             0.1244s              admin

** AFTER **

Finished in 0.95206 seconds (files took 8.81 seconds to load)
17 examples, 0 failures

Randomized with seed 27229

[TEST PROF INFO] Time spent in factories: 00:00.441 (14.48% of total time)
[TEST PROF INFO] Factories usage

 Total: 14
 Total top-level: 11
 Total time: 00:00.441 (out of 00:07.169)
 Total uniq factories: 9

   total   top-level     total time      time per call      top-level time               name

       3           0        0.0168s            0.0056s             0.0000s notification_setting
       2           2        0.0156s            0.0078s             0.0156s               user
       2           2        0.0121s            0.0061s             0.0121s        global_role
       2           2        0.0234s            0.0117s             0.0234s               role
       1           1        0.2310s            0.2310s             0.2310s            project
       1           1        0.0031s            0.0031s             0.0031s      global_member
       1           1        0.0440s            0.0440s             0.0440s              admin
       1           1        0.0872s            0.0872s             0.0872s              group
       1           1        0.0250s            0.0250s             0.0250s             member
2023-10-16 09:45:45 -05:00
Aaron Contreras a01ad36980 Lint: Address Rubocop offenses in cleanup_inherited_roles_integration_spec.rb
* Add `frozen_string_literal: true` magic comment.

* Use `contain_exactly` matcher instead of `match_array`
2023-10-16 09:39:38 -05:00
ulferts 8c291c0000 fix specs 2023-10-12 16:07:40 +02:00
ulferts 5b2bc41f41 Merge remote-tracking branch 'origin/dev' into easier-factory-role-setup 2023-10-12 12:09:27 +02:00
ulferts 2b2abf864a introduce ProjectRole model 2023-10-09 14:34:20 +02:00
Klaus Zanders 78c1e4fadb Switch all uses of principal factories to use new interface 2023-10-09 10:39:44 +02:00
Klaus Zanders 0148e5a1f7 Implement role denormalization of group memberships for users 2023-09-05 13:04:12 +02:00
Klaus Zanders fc99ed2afc Revert "Leave a TODO to add tests"
This reverts commit d0b4a0967d.
2023-08-08 10:09:02 +02:00
Klaus Zanders d0b4a0967d Leave a TODO to add tests 2023-08-08 10:04:05 +02:00
Christophe Bliard 4c2a9d0aa8 Enable RSpec zero monkey patching mode
The plan for RSpec 4.0 is to disable monkey patching.

See https://github.com/rspec/rspec-core/blob/main/features/configuration/zero_monkey_patching_mode.feature for details.
2023-05-31 19:22:29 +02:00
Christophe Bliard aa23106c11 lint: autocorrect RSpec/FactoryBot/ConsistentParenthesesStyle
command is

    rubocop -A --only RSpec/FactoryBot/ConsistentParenthesesStyle modules spec
2023-03-07 15:04:32 +01:00
Christophe Bliard a06e519ed7 Set send_notifications only when not nil
When calling a service with `send_notifications: false`, the
`Journal::NotificationConfiguration.active?` will be set to `false` and
subsequent calls to set it to `true` will have no effect and log a
warning.

For this reason, it's better to use `nil` as default value for
`send_notifications` so that
`Journal::NotificationConfiguration.active?` is changed only when the
value is explicitly `true` or `false`, and ignored when the value is
`nil`.
2023-02-27 17:47:34 +01:00
Oliver Günther 863ffe3341 Merge remote-tracking branch 'origin/release/12.4' into dev 2023-02-23 16:18:51 +01:00
Oliver Günther 447151fc98 Restore suppressing of notifications in groups service 2023-02-22 14:24:01 +01:00
Christophe Bliard 85b3258a29 Autocorrect with some rubocop cops
RSpec/Rails/InferredSpecType and Style/RedundantConstantBase

rubocop --autocorrect-all --only RSpec/Rails/InferredSpecType,Style/RedundantConstantBase spec modules/*/spec
2023-01-13 14:28:59 +01:00
Oliver Günther cbc05b0848 Merge remote-tracking branch 'origin/release/12.4' into dev 2023-01-04 20:50:41 +01:00
ulferts cbc7b9f124 optimize creating memberships for groups
Before, all the projects the group might have been in before the new
membership got created were considered by the SQL which potentially
results in a lot of records to be processed (the results were correct).
Now, only the project the new membership is created for is considered in
the SQL as that is the only project in which the group's users could
rightfully become members now.
2023-01-04 10:50:11 +01:00
Christophe Bliard 21a696ef9b Update copyright information for 2023 2022-12-30 15:51:26 +01:00
Christophe Bliard b50855a955 Use ServiceResult factory methods where possible
All was automatic through the use of `rubocop --autocorrect --only
OpenProject/UseServiceResultFactoryMethods app lib lib_static modules
spec`.
2022-06-16 10:01:57 +02:00
Christophe Bliard 48a4f1b6ad lint with rubocop --autocorrect (safe cops only) 2022-06-02 10:40:10 +02:00
ulferts 9b8e5d6216 keep roles inherited from different group on role adding 2022-04-26 20:44:00 +02:00
Christophe Bliard a33524ef6d remove ruby magic comment for utf-8
ruby interprets source encoding as utf-8 since 2.0.0, making magic comment redundant and useless
2022-03-10 19:36:58 +01:00
Christophe Bliard bc8d423ec2 update copyright information for 2022 2022-03-01 17:05:59 +01:00
Christophe Bliard 582c811091 fix bug: no more anonymous user when notifying of group membership removals
before, the email sent on group membership removal/ deletion was from Anonymous user. Now it is from the real user having performed the action in the administration
2022-01-31 18:25:22 +01:00
Christophe Bliard 632e1f7ec3 Make rubocop happier
Remove the 'FactoryBot.'
2022-01-31 09:32:49 +01:00
Christophe Bliard e6d75f8756 Cleanup global role associated with group when membership is deleted
It was already handled. Only tests were updated.
2022-01-31 09:32:33 +01:00
Christophe Bliard 7d862d4cc8 Update global role for users belonging to a group having global role 2022-01-31 09:32:32 +01:00
Christophe Bliard 482407392b add global role to users when added to a group having global role 2022-01-31 09:32:30 +01:00
Oliver Günther f08bea3467 Remove FactoryBot.* prefix where applicable 2022-01-25 08:19:06 +01:00
ulferts 816057e65e allow suppressing notifications on member create/update 2021-12-14 15:28:09 +01:00
Oliver Günther ccfa29c728 Move license and copyright docs to root, fix names and references 2021-09-02 21:50:46 +02:00
Oliver Günther b415c3771f Fix specs using a nil user context 2021-07-26 13:49:45 +02:00
Oliver Günther 843779c483 [38017] Don't remove group users if no replacement provided
https://community.openproject.org/wp/38017
2021-07-14 21:48:22 +02:00
ulferts d1f419385f Feature/member custom notifications (#9173)
* include custom message in membership forms

* keep pristine params to be able to pass it to the state

* fix indentation on projects api docs

* pass grape instance around in default endpoints

The grape instance has readily available access to all the objects (params, current_user) so less individual parameters need to be passed. This also avoids having to store the grape endpoint in a potentials not thread safe variable

* send custom message out on membership creation

* send custom message on membership update

* send custom message even if setting disabled

* restore params interface

* add custom message description to schema

* describe notificationMessage in the api documentation

* extract meta payload functionality into mixin

* ensure password in spec meets requirements

* Update docs/api/apiv3/endpoints/members.apib

Co-authored-by: Oliver Günther <mail@oliverguenther.de>

* Update docs/api/apiv3/endpoints/members.apib

Co-authored-by: Oliver Günther <mail@oliverguenther.de>

* Update docs/api/apiv3/endpoints/members.apib

Co-authored-by: Oliver Günther <mail@oliverguenther.de>

* Update docs/api/apiv3/endpoints/members.apib

Co-authored-by: Oliver Günther <mail@oliverguenther.de>

* Update docs/api/apiv3/endpoints/members.apib

Co-authored-by: Oliver Günther <mail@oliverguenther.de>

Co-authored-by: Oliver Günther <mail@oliverguenther.de>
2021-04-26 16:26:04 +02:00
ulferts 9fa5599392 Feature/member notifications (#8958)
* spec with correctly scoped links

* move db check into own file - fix deprecation

* basic spec for member creation service

* use constants for all notifications

* send an OP notification after member has been created

* send an OP notification after member has been updated

* mails on group member added

Depending on whether the membership existed before or not, an updated or
a created notification is send. This is done asynchronously.

* move all mail sender background jobs into namespace

* wip

* wip

* correct handling group member notifications

* add setting enable/disable mail sending on member alterations

* use services in members controller

* move Notifiable to OpenProject

* remove member after save hooks

* cleanup/testing/linting

* render member mails in receiver locale

* remove add_member! method

* use mailer layout for all mailers

* Update app/services/groups/cleanup_inherited_roles_service.rb

Co-authored-by: Oliver Günther <mail@oliverguenther.de>

* use around callback to avoid prepending

* handle nil params

Co-authored-by: Oliver Günther <mail@oliverguenther.de>
2021-04-20 13:45:42 +02:00
ulferts 7ecf08e005 rework changed_by_system (#9043)
Before, it was implemented by passing the changed attribut keys over to
the contract to whitelist them.

This lead to:
  * The contract interface becoming bloated
  * Having to rely on the knowledge of the developer not to falsely
    whitelist an attribute. The developer would also have to make sure
    to not perform a mass assignment after the attribute has been
    whitelisted

The new approach it to integrate the behaviour into the model which is
first altered in the service before it is scrutinized in the contract.

The information about the changed attributes is now stored inside the
model which removes the necessity to flag the whitelisted attribute
separately. Additionally, the exact change is tracked. So if an
attribute is set to one value inside a whitelisted block there is no
risk in later on performing a mass assignment.

This comes at the cost of extending the models which is weird also it is
build into the default SetAttributesService so child classes do not have
to worry. One might include the module into every AR model but currently
we only need it for a very specific use case.
2021-03-02 16:20:19 +01:00