Skip to content

Team membership approvals are not final and can be overriden #2824

Description

@kyteinsky

How to use GitHub

  • Please use the 👍 reaction to show that you are affected by the same issue.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

Steps to reproduce

  1. Create a new team "team5" as "admin" user
  2. Add "user1" and "user2"
  3. Assign an Admin role to user1
  4. Check/enable team properties:
    • Anyone can request membership
    • Members need to accept invitation
    • Memberships must be confirmed/accepted by a Moderator (requires "Anyone can request membership")
    • Visible to everyone
  5. Switch to "user4" and apply for a request to join team5
  6. Switch to user1 and approve the request
  7. (user4 gets added to the team)
  8. Switch to admin user and reject the request
  9. (user4 gets removed to the team)

Alternatively, if user1 rejects the request and admin approves it, admin gets a generic error "Failed to perform action" and the network log shows a generic 404.
^This one is a little hard to catch since the notification is removed soon but a helpful message would be nice nonetheless.

Expected behaviour

One approval from the notifications from any one of the admins/moderators should be final, and either the notifications from others users be removed or the actions there should be ignored if the user has been approved already.

Actual behaviour

Rejection from any one of the admins/moderators takes effect and removes the user.
Didn't test subsequent actions from additional admins/moderators from their notifications.

Server configuration

Web server: Apache/Nginx

Database: MySQL/Maria/SQLite/PostgreSQL

PHP version: 8.5/8.4/8.3

Nextcloud version: 34.0.3.2

List of activated apps
  - circles: 34.0.0
  - contacts: 8.8.0-rc.1
Nextcloud configuration
{
    "system": {
        "debug": true,
        "profiler": true,
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/apps-extra",
                "url": "\/apps-extra",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/apps-shared",
                "url": "\/apps-shared",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/apps-writable",
                "url": "\/apps-writable",
                "writable": true
            }
        ],
        "allow_local_remote_servers": true,
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpmode": "smtp",
        "mail_sendmailmode": "smtp",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "1025",
        "skeletondirectory": "\/skeleton",
        "setup_create_db_user": false,
        "loglevel": 2,
        "log_query": false,
        "query_log_file": "\/shared\/log\/querylog-stable34.log",
        "query_log_file_requestid": "yes",
        "diagnostics.logging": false,
        "diagnostics.logging.threshold": 0,
        "log.condition": {
            "apps": [
                "diagnostics",
                "admin_audit"
            ]
        },
        "sharing.federation.allowSelfSignedCertificates": true,
        "gss.selfsigned.allow": true,
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "localhost",
            "nextcloud",
            "stable34.nc.ncweb",
            "192.168.21.8",
            "localhost"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "mysql",
        "version": "34.0.3.2",
        "overwrite.cli.url": "https:\/\/stable34.nc.ncweb",
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "updater.release.channel": "git",
        "installed": true,
        "lookup_server": "",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "port": 6379
        },
        "memcache.local": "\\OC\\Memcache\\Redis",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
        "theme": "",
        "maintenance": false,
        "ldapProviderFactory": "OCA\\User_LDAP\\LDAPProviderFactory"
    }
}

Browser

Browser name: Firefox/Chrome/Safari/…

Browser version: 124/125/…

Operating system: Windows/Ubuntu/Mac/…

Server log

when the request if rejected then approved by another moderator:

{"reqId":"xo4Nkmn8kWoMaqBHDmyP","level":3,"time":"2026-08-27T00:29:11+00:00","remoteAddr":"192.168.21.4","user":"admin","app":"circles","method":"PUT","url":"/ocs/v2.php/apps/circles/circles/unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC/members/Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL","scriptName":"/ocs/v2.php","message":"{\"circleId\":\"unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC\",\"memberId\":\"Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL\"}","userAgent":"xxx","version":"34.0.3.2","exception":{"Exception":"OCA\\Circles\\Exceptions\\MemberNotFoundException","Message":"","Code":404,"Trace":[{"file":"/var/www/html/apps-extra/circles/lib/Db/MemberRequest.php","line":393,"function":"getItemFromRequest","class":"OCA\\Circles\\Db\\MemberRequestBuilder","type":"->","args":[{"__class__":"OCA\\Circles\\Db\\CoreQueryBuilder"}]},{"file":"/var/www/html/apps-extra/circles/lib/Service/MemberService.php","line":139,"function":"getMemberById","class":"OCA\\Circles\\Db\\MemberRequest","type":"->","args":["Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL",{"__class__":"OCA\\Circles\\Model\\FederatedUser"},{"__class__":"OCA\\Circles\\Model\\Probes\\MemberProbe"}]},{"file":"/var/www/html/apps-extra/circles/lib/Controller/LocalController.php","line":376,"function":"getMemberById","class":"OCA\\Circles\\Service\\MemberService","type":"->","args":["Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL","unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC"]},{"file":"/var/www/html/lib/private/AppFramework/Http/Dispatcher.php","line":165,"function":"memberConfirm","class":"OCA\\Circles\\Controller\\LocalController","type":"->","args":["unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC","Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL"]},{"file":"/var/www/html/lib/private/AppFramework/Http/Dispatcher.php","line":78,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OCA\\Circles\\Controller\\LocalController"},"memberConfirm"]},{"file":"/var/www/html/lib/private/AppFramework/App.php","line":137,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OCA\\Circles\\Controller\\LocalController"},"memberConfirm"]},{"file":"/var/www/html/lib/private/Route/Router.php","line":324,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OCA\\Circles\\Controller\\LocalController","memberConfirm",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"ocs.circles.local.memberconfirm","circleId":"unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC","memberId":"Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL"}]},{"file":"/var/www/html/ocs/v1.php","line":78,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/ocsapp/apps/circles/circles/unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC/members/Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL"]},{"file":"/var/www/html/ocs/v2.php","line":10,"args":["/var/www/html/ocs/v1.php"],"function":"require_once"}],"File":"/var/www/html/apps-extra/circles/lib/Db/MemberRequestBuilder.php","Line":102,"message":"{\"circleId\":\"unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC\",\"memberId\":\"Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL\"}","exception":"{\"class\":\"OCA\\Circles\\Exceptions\\MemberNotFoundException\",\"message\":\"\",\"code\":404,\"file\":\"/var/www/html/apps-extra/circles/lib/Db/MemberRequestBuilder.php:102\",\"trace\":\"#0 /var/www/html/apps-extra/circles/lib/Db/MemberRequest.php(393): OCA\\Circles\\Db\\MemberRequestBuilder->getItemFromRequest(Object(OCA\\Circles\\Db\\CoreQueryBuilder))\\n#1 /var/www/html/apps-extra/circles/lib/Service/MemberService.php(139): OCA\\Circles\\Db\\MemberRequest->getMemberById('Cd2CGENqqHK1dGp...', Object(OCA\\Circles\\Model\\FederatedUser), Object(OCA\\Circles\\Model\\Probes\\MemberProbe))\\n#2 /var/www/html/apps-extra/circles/lib/Controller/LocalController.php(376): OCA\\Circles\\Service\\MemberService->getMemberById('Cd2CGENqqHK1dGp...', 'unA8Pi4zzB18bzD...')\\n#3 /var/www/html/lib/private/AppFramework/Http/Dispatcher.php(165): OCA\\Circles\\Controller\\LocalController->memberConfirm('unA8Pi4zzB18bzD...', 'Cd2CGENqqHK1dGp...')\\n#4 /var/www/html/lib/private/AppFramework/Http/Dispatcher.php(78): OC\\AppFramework\\Http\\Dispatcher->executeController(Object(OCA\\Circles\\Controller\\LocalController), 'memberConfirm')\\n#5 /var/www/html/lib/private/AppFramework/App.php(137): OC\\AppFramework\\Http\\Dispatcher->dispatch(Object(OCA\\Circles\\Controller\\LocalController), 'memberConfirm')\\n#6 /var/www/html/lib/private/Route/Router.php(324): OC\\AppFramework\\App::main('OCA\\\\Circles\\\\Con...', 'memberConfirm', Object(OC\\AppFramework\\DependencyInjection\\DIContainer), Array)\\n#7 /var/www/html/ocs/v1.php(78): OC\\Route\\Router->match('/ocsapp/apps/ci...')\\n#8 /var/www/html/ocs/v2.php(10): require_once('/var/www/html/o...')\\n#9 {main}\"}","CustomMessage":"{\"circleId\":\"unA8Pi4zzB18bzD9WRsLZ7Yj6JsyjLC\",\"memberId\":\"Cd2CGENqqHK1dGpa9wFJJ4tKS9kytwL\"}"}}

another error for the same case from a different system, maybe it's useful:

{"reqId":"VItLHnJ6lCJ0QHIpGDjd","level":3,"time":"2026-08-19 11:30:50","remoteAddr":"xxx","user":"TeamModerator","app":"circles","method":"PUT","url":"/ocs/v2.php/apps/circles/circles/FjbM8Rj6TjWUNGUUG2TLIqZ7vyJIbkd/members/NeqYFrRKk2srSmIc3niWcsn9Qg1gSx5","scriptName":"/ocs/v2.php","message":"{\"circleId\":\"FjbM8Rj6TjWUNGUUG2TLIqZ7vyJIbkd\",\"memberId\":\"NeqYFrRKk2srSmIc3niWcsn9Qg1gSx5\"}","userAgent":"xxx","version":"34.0.3.2","exception":{"Exception":"OCA\\Circles\\Exceptions\\FederatedItemBadRequestException","Message":"Already member of the team","Code":122,"Trace":[{"file":"/var/www/html/nextcloud/apps/circles/lib/FederatedItems/SingleMemberAdd.php","line":243,"function":"manageMemberStatus","class":"OCA\\Circles\\FederatedItems\\SingleMemberAdd","type":"->"},{"file":"/var/www/html/nextcloud/apps/circles/lib/FederatedItems/SingleMemberAdd.php","line":114,"function":"generateMember","class":"OCA\\Circles\\FederatedItems\\SingleMemberAdd","type":"->"},{"file":"/var/www/html/nextcloud/apps/circles/lib/Service/FederatedEventService.php","line":116,"function":"verify","class":"OCA\\Circles\\FederatedItems\\SingleMemberAdd","type":"->"},{"file":"/var/www/html/nextcloud/apps/circles/lib/Service/MemberService.php","line":223,"function":"newEvent","class":"OCA\\Circles\\Service\\FederatedEventService","type":"->"},{"file":"/var/www/html/nextcloud/apps/circles/lib/Controller/LocalController.php","line":380,"function":"addMember","class":"OCA\\Circles\\Service\\MemberService","type":"->"},{"file":"/var/www/html/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":165,"function":"memberConfirm","class":"OCA\\Circles\\Controller\\LocalController","type":"->"},{"file":"/var/www/html/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":78,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->"},{"file":"/var/www/html/nextcloud/lib/private/AppFramework/App.php","line":137,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->"},{"file":"/var/www/html/nextcloud/lib/private/Route/Router.php","line":324,"function":"main","class":"OC\\AppFramework\\App","type":"::"},{"file":"/var/www/html/nextcloud/ocs/v1.php","line":78,"function":"match","class":"OC\\Route\\Router","type":"->"},{"file":"/var/www/html/nextcloud/ocs/v2.php","line":10,"args":["/var/www/html/nextcloud/ocs/v1.php"],"function":"require_once"}],"File":"/var/www/html/nextcloud/apps/circles/lib/FederatedItems/SingleMemberAdd.php","Line":296,"message":"{\"circleId\":\"FjbM8Rj6TjWUNGUUG2TLIqZ7vyJIbkd\",\"memberId\":\"NeqYFrRKk2srSmIc3niWcsn9Qg1gSx5\"}","exception":"{\"class\":\"OCA\\Circles\\Exceptions\\FederatedItemBadRequestException\",\"message\":\"Already member of the team\",\"code\":122,\"file\":\"/var/www/html/nextcloud/apps/circles/lib/FederatedItems/SingleMemberAdd.php:296\",\"trace\":\"#0 /var/www/html/nextcloud/apps/circles/lib/FederatedItems/SingleMemberAdd.php(243): OCA\\Circles\\FederatedItems\\SingleMemberAdd->manageMemberStatus()\\n#1 /var/www/html/nextcloud/apps/circles/lib/FederatedItems/SingleMemberAdd.php(114): OCA\\Circles\\FederatedItems\\SingleMemberAdd->generateMember()\\n#2 /var/www/html/nextcloud/apps/circles/lib/Service/FederatedEventService.php(116): OCA\\Circles\\FederatedItems\\SingleMemberAdd->verify()\\n#3 /var/www/html/nextcloud/apps/circles/lib/Service/MemberService.php(223): OCA\\Circles\\Service\\FederatedEventService->newEvent()\\n#4 /var/www/html/nextcloud/apps/circles/lib/Controller/LocalController.php(380): OCA\\Circles\\Service\\MemberService->addMember()\\n#5 /var/www/html/nextcloud/lib/private/AppFramework/Http/Dispatcher.php(165): OCA\\Circles\\Controller\\LocalController->memberConfirm()\\n#6 /var/www/html/nextcloud/lib/private/AppFramework/Http/Dispatcher.php(78): OC\\AppFramework\\Http\\Dispatcher->executeController()\\n#7 /var/www/html/nextcloud/lib/private/AppFramework/App.php(137): OC\\AppFramework\\Http\\Dispatcher->dispatch()\\n#8 /var/www/html/nextcloud/lib/private/Route/Router.php(324): OC\\AppFramework\\App::main()\\n#9 /var/www/html/nextcloud/ocs/v1.php(78): OC\\Route\\Router->match()\\n#10 /var/www/html/nextcloud/ocs/v2.php(10): require_once('...')\\n#11 {main}\"}","CustomMessage":"{\"circleId\":\"FjbM8Rj6TjWUNGUUG2TLIqZ7vyJIbkd\",\"memberId\":\"NeqYFrRKk2srSmIc3niWcsn9Qg1gSx5\"}"}}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions