MerginMaps / MerginMaps/server

Newly created project gets no project_member row — creator holds no role, sharing is impossible

Open Beginner friendly
#659 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
179
Forks
71
Avg merge
1d 4h
Merged PRs (30d)
10

Description

Summary

add_project() never grants the creator a role on the new project. No row is written to
project_member at all, so the project ends up with no roles whatsoever.

Consequences:

  1. Sharing is broken. With no roles on the project, the web UI's Collaborators page cannot add
    anyone — including the owner adding themselves. This was the presenting symptom for us.
  2. With GLOBAL_ADMIN=True, the creator cannot see their own project.

Environment

Image lutraconsulting/merginmaps-backend:2025.7.3 (self-reports 2025.6.2, see #548)
Deployment self-hosted CE, Docker Compose, single global workspace
Config GLOBAL_READ / GLOBAL_WRITE / GLOBAL_ADMIN all unset (default False)

Verified still present in the current sourceadd_project() is structurally unchanged at
2025.7.3, 2025.8.0, 2025.8.1, 2025.8.2, 2026.4.2, 2026.5.0, 2026.6.0 and 2026.6.2.
None of them calls set_role.

Steps to reproduce

  1. Create a project — web UI or POST /v1/project/{namespace}; both reproduce it.
  2. Query the database:
SELECT p.name, u.username, pm.role
FROM project p
LEFT JOIN project_member pm ON pm.project_id = p.id
LEFT JOIN "user" u ON u.id = pm.user_id
WHERE p.name = '<new project>';

Expected: the creator holds owner.
Actual: no rows.

Observed on two projects created by two different users through two different paths:

schema-change-test | (NO MEMBERS)     <- created in the web UI by a superuser
list-refresh-test  | (NO MEMBERS)     <- created via the REST API by a non-superuser

Two older projects on the same server do have admin:owner rows — they were migrated in from
another host with their rows already present, which is why this went unnoticed at first.

Why the creator loses visibility

GlobalWorkspaceHandler.get_user_role() returns OWNER for is_admin users and GUEST for
everyone else when the GLOBAL_* settings are at their defaults. A GUEST reaches a project only
via project_member or Project.public — so a non-superuser who creates a project immediately
cannot see it.

Reproduced with a non-superuser that had been granted create rights:

GET /v1/project/paginated?flag=created   ->  count=0

flag=created filters on Project.creator_id == user.id and the user is the creator, but
projects_query(ProjectPermissions.Read) discards the project before the creator test is reached.

Cause

server/mergin/sync/public_api_controller.py, add_project() builds the project with
creator=current_user, adds a ProjectVersion, and commits — but never calls set_role.
Project.__init__ (sync/models.py) sets self.creator and does not call it either. The only
callers of set_role are the explicit collaborator endpoints in public_api_v2_controller.py.

Suggested fix

In add_project(), before db.session.commit():

p.set_role(current_user.id, ProjectRole.OWNER)

A data migration granting owner to creator_id for existing projects that have no
project_member rows would repair servers already affected.

I'm happy to open a PR for this if it would be useful.

Workaround

INSERT INTO project_member (project_id, user_id, role)
SELECT p.id, u.id, 'owner'::project_role
FROM project p JOIN "user" u ON u.username = '<owner>'
WHERE p.name = '<project>'
ON CONFLICT DO NOTHING;

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

Start in server/mergin/sync/public_api_controller.py at add_project(), then inspect Project.init in sync/models.py and the set_role callers in public_api_v2_controller.py. Exercise POST /v1/project/{namespace} and verify a newly created project has an owner project_member row and remains visible to its creator; consider the stated migration separately for existing projects without members.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, sql
Domain
api, authorization, backend, database
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.