nextcloud / nextcloud/circles

Actions that cannot be performed are visible in the team members list

Open
#2,808 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

0. Needs triage bug
Dominant language
JavaScript
Stars
177
Forks
68
Avg merge
2d 22h
Merged PRs (30d)
60

Description

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 "team3" as user "admin"
  2. Add two new users "user1" and "user2"
  3. Login with user1
  4. (no actions visible for other members in Contacts -> team3)
  5. As user admin, allow option "Members can also invite"
  6. As user1, see trash icon beside the other "Member"s
  7. Clicking on them shows the error "Could not delete the member user4", and Error 403 in the logs, "Insufficient permissions to perform this action"
Expected behaviour

The icons should not be visible.

Actual behaviour

Icons are visible.

Image

Another case, when user1 is a Moderator, it has the option to promote itself to Admin:

Image
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"
    }
}

Server log

In case of Moderator trying to become an Admin:

{"reqId":"WjBSWZRcd7k9PWDPXVf9","level":3,"time":"2026-08-25T07:16:49+00:00","remoteAddr":"192.168.21.3","user":"user1","app":"circles","method":"PUT","url":"/ocs/v2.php/apps/circles/circles/zw737qOvOVVXh76L5jNjtKf5T7OcFUI/members/mgDrA1fhn1e9kjC6tWhdLsXsqHkny21/level","scriptName":"/ocs/v2.php","message":"{\"circleId\":\"zw737qOvOVVXh76L5jNjtKf5T7OcFUI\",\"memberId\":\"mgDrA1fhn1e9kjC6tWhdLsXsqHkny21\",\"level\":8}","userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36","version":"34.0.3.2","exception":{"Exception":"OCA\\Circles\\Exceptions\\MemberLevelException","Message":"Insufficient rights","Code":400,"Trace":[{"file":"/var/www/html/apps-extra/circles/lib/FederatedItems/MemberLevel.php","line":170,"function":"mustHaveLevelAboveOrEqual","class":"OCA\\Circles\\Model\\Helpers\\MemberHelper","type":"->","args":[8]},{"file":"/var/www/html/apps-extra/circles/lib/FederatedItems/MemberLevel.php","line":109,"function":"verifyMemberLevel","class":"OCA\\Circles\\FederatedItems\\MemberLevel","type":"->","args":[{"__class__":"OCA\\Circles\\Model\\Member"},{"__class__":"OCA\\Circles\\Model\\Member"},8]},{"file":"/var/www/html/apps-extra/circles/lib/Service/FederatedEventService.php","line":116,"function":"verify","class":"OCA\\Circles\\FederatedItems\\MemberLevel","type":"->","args":[{"__class__":"OCA\\Circles\\Model\\Federated\\FederatedEvent"}]},{"file":"/var/www/html/apps-extra/circles/lib/Service/MemberService.php","line":361,"function":"newEvent","class":"OCA\\Circles\\Service\\FederatedEventService","type":"->","args":[{"__class__":"OCA\\Circles\\Model\\Federated\\FederatedEvent"}]},{"file":"/var/www/html/apps-extra/circles/lib/Controller/LocalController.php","line":351,"function":"memberLevel","class":"OCA\\Circles\\Service\\MemberService","type":"->","args":["mgDrA1fhn1e9kjC6tWhdLsXsqHkny21",8]},{"file":"/var/www/html/lib/private/AppFramework/Http/Dispatcher.php","line":165,"function":"memberLevel","class":"OCA\\Circles\\Controller\\LocalController","type":"->","args":["zw737qOvOVVXh76L5jNjtKf5T7OcFUI","mgDrA1fhn1e9kjC6tWhdLsXsqHkny21",8]},{"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"},"memberLevel"]},{"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"},"memberLevel"]},{"file":"/var/www/html/lib/private/Route/Router.php","line":324,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OCA\\Circles\\Controller\\LocalController","memberLevel",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"ocs.circles.local.memberlevel","circleId":"zw737qOvOVVXh76L5jNjtKf5T7OcFUI","memberId":"mgDrA1fhn1e9kjC6tWhdLsXsqHkny21"}]},{"file":"/var/www/html/ocs/v1.php","line":78,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/ocsapp/apps/circles/circles/zw737qOvOVVXh76L5jNjtKf5T7OcFUI/members/mgDrA1fhn1e9kjC6tWhdLsXsqHkny21/level"]},{"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/Model/Helpers/MemberHelper.php","Line":132,"message":"{\"circleId\":\"zw737qOvOVVXh76L5jNjtKf5T7OcFUI\",\"memberId\":\"mgDrA1fhn1e9kjC6tWhdLsXsqHkny21\",\"level\":8}","exception":"{\"class\":\"OCA\\Circles\\Exceptions\\MemberLevelException\",\"message\":\"Insufficient rights\",\"code\":400,\"file\":\"/var/www/html/apps-extra/circles/lib/Model/Helpers/MemberHelper.php:132\",\"trace\":\"#0 /var/www/html/apps-extra/circles/lib/FederatedItems/MemberLevel.php(170): OCA\\Circles\\Model\\Helpers\\MemberHelper->mustHaveLevelAboveOrEqual(8)\\n#1 /var/www/html/apps-extra/circles/lib/FederatedItems/MemberLevel.php(109): OCA\\Circles\\FederatedItems\\MemberLevel->verifyMemberLevel(Object(OCA\\Circles\\Model\\Member), Object(OCA\\Circles\\Model\\Member), 8)\\n#2 /var/www/html/apps-extra/circles/lib/Service/FederatedEventService.php(116): OCA\\Circles\\FederatedItems\\MemberLevel->verify(Object(OCA\\Circles\\Model\\Federated\\FederatedEvent))\\n#3 /var/www/html/apps-extra/circles/lib/Service/MemberService.php(361): OCA\\Circles\\Service\\FederatedEventService->newEvent(Object(OCA\\Circles\\Model\\Federated\\FederatedEvent))\\n#4 /var/www/html/apps-extra/circles/lib/Controller/LocalController.php(351): OCA\\Circles\\Service\\MemberService->memberLevel('mgDrA1fhn1e9kjC...', 8)\\n#5 /var/www/html/lib/private/AppFramework/Http/Dispatcher.php(165): OCA\\Circles\\Controller\\LocalController->memberLevel('zw737qOvOVVXh76...', 'mgDrA1fhn1e9kjC...', 8)\\n#6 /var/www/html/lib/private/AppFramework/Http/Dispatcher.php(78): OC\\AppFramework\\Http\\Dispatcher->executeController(Object(OCA\\Circles\\Controller\\LocalController), 'memberLevel')\\n#7 /var/www/html/lib/private/AppFramework/App.php(137): OC\\AppFramework\\Http\\Dispatcher->dispatch(Object(OCA\\Circles\\Controller\\LocalController), 'memberLevel')\\n#8 /var/www/html/lib/private/Route/Router.php(324): OC\\AppFramework\\App::main('OCA\\\\Circles\\\\Con...', 'memberLevel', Object(OC\\AppFramework\\DependencyInjection\\DIContainer), Array)\\n#9 /var/www/html/ocs/v1.php(78): OC\\Route\\Router->match('/ocsapp/apps/ci...')\\n#10 /var/www/html/ocs/v2.php(10): require_once('/var/www/html/o...')\\n#11 {main}\"}","CustomMessage":"{\"circleId\":\"zw737qOvOVVXh76L5jNjtKf5T7OcFUI\",\"memberId\":\"mgDrA1fhn1e9kjC6tWhdLsXsqHkny21\",\"level\":8}"}}
Browser

Browser name: Chrome

Browser version: 151

Operating system: Linux/docker compose

Browser log
{"ocs":{"meta":{"status":"failure","statuscode":403,"message":""},"data":{"message":"Insufficient permissions to perform this action"}}}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the team member list actions and compare their visibility with the permission checks in lib/Controller/LocalController.php and lib/Model/Helpers/MemberHelper.php. Start from the memberLevel entry point and the reported 403 response, then verify that unauthorized delete and promotion controls are hidden and do not trigger those requests.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, php
Domain
api, authorization, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
66/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.