Consider the scenario:
1. The default visibility level is set to internal
2. A user attempts to create a private project within a private group
Previously this would always fail because default_value_for would
overwrite the private visibility setting, no matter what
visibility_level were specified. This was happening because
default_value_for was confused by the default value of 0 specified by
the database schema.
default_value_for attempts to assign the default value in the block by
checking whether the attribute has changed. The problem is that since
the default value by the database was 0, and the user requested 0, this
appeared as though no changes were made. As a result, default_value_for
would always overwrite the user's preference.
To fix this, we remove the use of default_value_for and only set the
visibility level to the default application setting when no preference
has been given at creation time.
Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/63158
In CE only the admin has access to all private groups & projects. In EE also an
auditor can have full private access.
To overcome merge conflicts, or accidental incorrect access rights, abstract
this out in `User#full_private_access?`.
`User#admin?` now only should be used for admin-only features. For private
access-related features `User#full_private_access?` should be used.
Backported from gitlab-org/gitlab-ee!2199
This changes ProjectsFinder#init_collection so it no longer relies on a
UNION. For example, to get starred projects of a user we used to run:
SELECT projects.*
FROM projects
WHERE projects.pending_delete = 'f'
AND (
projects.id IN (
SELECT projects.id
FROM projects
INNER JOIN users_star_projects
ON users_star_projects.project_id = projects.id
INNER JOIN project_authorizations
ON projects.id = project_authorizations.project_id
WHERE projects.pending_delete = 'f'
AND project_authorizations.user_id = 1
AND users_star_projects.user_id = 1
UNION
SELECT projects.id
FROM projects
INNER JOIN users_star_projects
ON users_star_projects.project_id = projects.id
WHERE projects.visibility_level IN (20, 10)
AND users_star_projects.user_id = 1
)
)
ORDER BY projects.id DESC;
With these changes the above query is turned into the following instead:
SELECT projects.*
FROM projects
INNER JOIN users_star_projects
ON users_star_projects.project_id = projects.id
WHERE projects.pending_delete = 'f'
AND (
EXISTS (
SELECT 1
FROM project_authorizations
WHERE project_authorizations.user_id = 1
AND (project_id = projects.id)
)
OR projects.visibility_level IN (20,10)
)
AND users_star_projects.user_id = 1
ORDER BY projects.id DESC;
This query in turn produces a better execution plan and takes less time,
though the difference is only a few milliseconds (this however depends
on the amount of data involved and additional conditions that may be
added).
When a VisibilityLevel is an integer formatted as a string, convert it
to an integer, instead of looking it up in the hash map.
When the value is not recognized, default to PRIVATE.
For the API, the VisibilityLevel will be exposed as String instead of
Integer. So add the string values and method to translate a level
integer to a string.
Added visibility_level icons to project view (rather than just text).
Added public projects to search results.
Added ability to restrict visibility levels standard users can set.