From 62e1ab73e2cf815df0d21f8bd3de996a4624bae2 Mon Sep 17 00:00:00 2001 From: Dominik Wombacher Date: Apr 26 2024 08:46:36 +0000 Subject: feat!: Drop gitolite backend support BREAKING CHANGE: this commit drops 'gitolite2' and 'gitolite3' backend support. 'pagure' is the new default backend. Code to support 'static' backends removed. --- diff --git a/UPGRADING.rst b/UPGRADING.rst index 7ca0682..2f1c34c 100644 --- a/UPGRADING.rst +++ b/UPGRADING.rst @@ -13,6 +13,7 @@ The 6.0 release contains database schema updates, so: Removed features (in 6.0): * repoSpanner, which was never completed and eventually abandoned. +* gitolite, ``pagure_authorized_keys`` is now the default auth backend. Configuration keys removed (in 6.0); @@ -22,6 +23,19 @@ Configuration keys removed (in 6.0); * REPOSPANNER_NEW_FORK * REPOSPANNER_ADMIN_MIGRATION * REPOSPANNER_REGIONS +* GITOLITE_CONFIG +* GITOLITE_HOME +* GITOLITE_VERSION +* GITOLITE_KEYDIR +* GITOLITE_BACKEND +* GITOLITE_HAS_COMPILE_1 +* GL_RC +* GL_BINDIR +* HTTP_REPO_ACCESS_GITOLITE +* GITOLITE_CELERY_QUEUE +* GL_REPO_BASE +* GITOLITE_PRE_CONFIG +* GITOLITE_POST_CONFIG From 5.12 to 5.13 diff --git a/alembic/versions/6a8ca213d503_drop_project_read_only_column.py b/alembic/versions/6a8ca213d503_drop_project_read_only_column.py new file mode 100644 index 0000000..c06c5e6 --- /dev/null +++ b/alembic/versions/6a8ca213d503_drop_project_read_only_column.py @@ -0,0 +1,23 @@ +"""Drop project read_only column + +Revision ID: 6a8ca213d503 +Revises: 5df8314dfc13 +Create Date: 2024-04-24 21:49:11.394451 + +""" + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '6a8ca213d503' +down_revision = '5df8314dfc13' + + +def upgrade(): + op.drop_column('projects', 'read_only') + + +def downgrade(): + op.add_column('projects', sa.Column('read_only', sa.Boolean(), default=True, nullable=False)) diff --git a/dev/ansible/roles/pagure-dev/files/gitolite3.rc b/dev/ansible/roles/pagure-dev/files/gitolite3.rc deleted file mode 100644 index 9c566f4..0000000 --- a/dev/ansible/roles/pagure-dev/files/gitolite3.rc +++ /dev/null @@ -1,196 +0,0 @@ -# configuration variables for gitolite - -# This file is in perl syntax. But you do NOT need to know perl to edit it -- -# just mind the commas, use single quotes unless you know what you're doing, -# and make sure the brackets and braces stay matched up! - -# (Tip: perl allows a comma after the last item in a list also!) - -# HELP for commands can be had by running the command with "-h". - -# HELP for all the other FEATURES can be found in the documentation (look for -# "list of non-core programs shipped with gitolite" in the master index) or -# directly in the corresponding source file. - -%RC = ( - - # ------------------------------------------------------------------ - GL_REPO_BASE => '/home/vagrant/pagure_data/repos', - - # default umask gives you perms of '0700'; see the rc file docs for - # how/why you might change this - UMASK => 0077, - - # look for "git-config" in the documentation - GIT_CONFIG_KEYS => '', - - # comment out if you don't need all the extra detail in the logfile - LOG_EXTRA => 1, - # syslog options - # 1. leave this section as is for normal gitolite logging - # 2. uncomment this line to log only to syslog: - # LOG_DEST => 'syslog', - # 3. uncomment this line to log to syslog and the normal gitolite log: - # LOG_DEST => 'syslog,normal', - - # roles. add more roles (like MANAGER, TESTER, ...) here. - # WARNING: if you make changes to this hash, you MUST run 'gitolite - # compile' afterward, and possibly also 'gitolite trigger POST_COMPILE' - ROLES => { - READERS => 1, - WRITERS => 1, - }, - - # enable caching (currently only Redis). PLEASE RTFM BEFORE USING!!! - # CACHE => 'Redis', - - # ------------------------------------------------------------------ - - # rc variables used by various features - - # the 'info' command prints this as additional info, if it is set - # SITE_INFO => 'Please see http://blahblah/gitolite for more help', - - # the CpuTime feature uses these - # display user, system, and elapsed times to user after each git operation - # DISPLAY_CPU_TIME => 1, - # display a warning if total CPU times (u, s, cu, cs) crosses this limit - # CPU_TIME_WARN_LIMIT => 0.1, - - # the Mirroring feature needs this - # HOSTNAME => "foo", - - # TTL for redis cache; PLEASE SEE DOCUMENTATION BEFORE UNCOMMENTING! - # CACHE_TTL => 600, - - # ------------------------------------------------------------------ - - # suggested locations for site-local gitolite code (see cust.html) - - # this one is managed directly on the server - # LOCAL_CODE => "$ENV{HOME}/local", - - # or you can use this, which lets you put everything in a subdirectory - # called "local" in your gitolite-admin repo. For a SECURITY WARNING - # on this, see http://gitolite.com/gitolite/non-core.html#pushcode - # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local", - - # ------------------------------------------------------------------ - - # List of commands and features to enable - - ENABLE => [ - - # COMMANDS - - # These are the commands enabled by default - 'help', - 'desc', - 'info', - 'perms', - 'writable', - - # Uncomment or add new commands here. - # 'create', - # 'fork', - # 'mirror', - # 'readme', - # 'sskm', - # 'D', - - # These FEATURES are enabled by default. - - # essential (unless you're using smart-http mode) - 'ssh-authkeys', - - # creates git-config enties from gitolite.conf file entries like 'config foo.bar = baz' - 'git-config', - - # creates git-daemon-export-ok files; if you don't use git-daemon, comment this out - 'daemon', - - # creates projects.list file; if you don't use gitweb, comment this out - #'gitweb', - - # These FEATURES are disabled by default; uncomment to enable. If you - # need to add new ones, ask on the mailing list :-) - - # user-visible behaviour - - # prevent wild repos auto-create on fetch/clone - # 'no-create-on-read', - # no auto-create at all (don't forget to enable the 'create' command!) - # 'no-auto-create', - - # access a repo by another (possibly legacy) name - # 'Alias', - - # give some users direct shell access. See documentation in - # sts.html for details on the following two choices. - # "Shell $ENV{HOME}/.gitolite.shell-users", - # 'Shell alice bob', - - # set default roles from lines like 'option default.roles-1 = ...', etc. - # 'set-default-roles', - - # show more detailed messages on deny - # 'expand-deny-messages', - - # show a message of the day - # 'Motd', - - # system admin stuff - - # enable mirroring (don't forget to set the HOSTNAME too!) - # 'Mirroring', - - # allow people to submit pub files with more than one key in them - # 'ssh-authkeys-split', - - # selective read control hack - # 'partial-copy', - - # manage local, gitolite-controlled, copies of read-only upstream repos - # 'upstream', - - # updates 'description' file instead of 'gitweb.description' config item - # 'cgit', - - # allow repo-specific hooks to be added - # 'repo-specific-hooks', - - # performance, logging, monitoring... - - # be nice - # 'renice 10', - - # log CPU times (user, system, cumulative user, cumulative system) - # 'CpuTime', - - # syntactic_sugar for gitolite.conf and included files - - # allow backslash-escaped continuation lines in gitolite.conf - # 'continuation-lines', - - # create implicit user groups from directory names in keydir/ - # 'keysubdirs-as-groups', - - # allow simple line-oriented macros - # 'macros', - - # Kindergarten mode - - # disallow various things that sensible people shouldn't be doing anyway - # 'Kindergarten', - ], - -); - -# ------------------------------------------------------------------------------ -# per perl rules, this should be the last line in such a file: -1; - -# Local variables: -# mode: perl -# End: -# vim: set syn=perl: diff --git a/dev/ansible/roles/pagure-dev/files/pagure.cfg b/dev/ansible/roles/pagure-dev/files/pagure.cfg index 7085dea..1f66b30 100644 --- a/dev/ansible/roles/pagure-dev/files/pagure.cfg +++ b/dev/ansible/roles/pagure-dev/files/pagure.cfg @@ -199,6 +199,5 @@ LOGGING = { }, } -HTTP_REPO_ACCESS_GITOLITE = None SSH_KEYS_USERNAME_EXPECT = "git" ALLOW_HTTP_PUSH = True diff --git a/dev/ansible/roles/pagure-dev/tasks/gitolite.yml b/dev/ansible/roles/pagure-dev/tasks/gitolite.yml deleted file mode 100644 index 2859409..0000000 --- a/dev/ansible/roles/pagure-dev/tasks/gitolite.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -- name: Install gitolite3 - dnf: - name: - - gitolite3 - state: present - -- name: Install gitolite.rc to ~/.gitolite.rc - become_user: "{{ ansible_env.SUDO_USER }}" - copy: - src: gitolite3.rc - dest: /home/{{ ansible_env.SUDO_USER }}/.gitolite.rc - -- name: Create a key for gitolite - become_user: "{{ ansible_env.SUDO_USER }}" - command: ssh-keygen -f gitolite_rsa -t rsa -N '' - args: - chdir: /home/{{ ansible_env.SUDO_USER }} - creates: /home/{{ ansible_env.SUDO_USER }}/gitolite_rsa.pub - -- name: Setup gitolite - become_user: "{{ ansible_env.SUDO_USER }}" - command: gitolite setup -pk gitolite_rsa.pub - args: - chdir: /home/{{ ansible_env.SUDO_USER }} diff --git a/dev/ansible/roles/pagure-dev/tasks/main.yml b/dev/ansible/roles/pagure-dev/tasks/main.yml index 022b6d6..fdc8a02 100644 --- a/dev/ansible/roles/pagure-dev/tasks/main.yml +++ b/dev/ansible/roles/pagure-dev/tasks/main.yml @@ -2,7 +2,6 @@ - import_tasks: clamav.yml - import_tasks: eventsource.yml -#- include: gitolite.yml - import_tasks: milter.yml - import_tasks: postgres.yml diff --git a/doc/configuration.rst b/doc/configuration.rst index 9053c5c..047e960 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -140,10 +140,6 @@ For every project, two to four repos are created: (if ``ENABLE_TICKETS`` is ``True``) * a repo with metadata of pull requests opened against the project -Note that gitolite config value ``GL_REPO_BASE`` (if using gitolite 3) -or ``$REPO_BASE`` (if using gitolite 2) **must** have exactly the same -value as ``GIT_FOLDER``. - REMOTE_GIT_FOLDER ~~~~~~~~~~~~~~~~~ @@ -243,24 +239,14 @@ GIT_AUTH_BACKEND This configuration key allows specifying which git auth backend to use. -Git auth backends can either be static (like gitolite), where a file is -generated when something changed and then used on login, or dynamic, -where the actual ACLs are checked in a git hook before being applied. - By default pagure provides the following backends: - `test_auth`: simple debugging backend printing and returning the string ``Called GitAuthTestHelper.generate_acls()`` -- `gitolite2`: allows deploying pagure on the top of gitolite 2 -- `gitolite3`: allows deploying pagure on the top of gitolite 3 - `pagure`: Pagure git auth implementation (using keyhelper.py and aclchecker.py) that is used via sshd AuthorizedKeysCommand - `pagure_authorized_keys`: Pagure git auth implementation that writes to authorized_keys file Defaults to: ``pagure_authorized_keys`` -.. note:: The option GITOLITE_BACKEND is the legacy name, and for backwards compatibility reasons will override this setting - -.. note:: These options can be expended, cf :ref:`custom-gitolite`. - Configure Pagure Auth --------------------- @@ -290,8 +276,6 @@ To use this variant, set the following in ``pagure.cfg``: GIT_AUTH_BACKEND = "pagure" - HTTP_REPO_ACCESS_GITOLITE = None - SSH_KEYS_USERNAME_EXPECT = "git" SSH_COMMAND = ([ @@ -327,150 +311,12 @@ set the following to ``pagure.cfg``: GIT_AUTH_BACKEND = "pagure_authorized_keys" - HTTP_REPO_ACCESS_GITOLITE = None - SSH_COMMAND = ([ "/usr/bin/%(cmd)s", "/srv/git/repositories/%(reponame)s", ], {"GL_USER": "%(username)s"}) -Configure Gitolite ------------------- - -Pagure can use `gitolite `_ as an authorization layer. -Gitolite relies on `SSH `_ for -the authentication. In other words, SSH lets you in and gitolite checks if -you are allowed to do what you are trying to do once you are inside. - -Pagure supports both gitolite 2 and gitolite 3 and the code generating -the gitolite configuration can be customized for easier integration with -other systems (cf :ref:`custom-gitolite`). - -Using Gitolite also requires setting the following in ``pagure.cfg``: - -:: - - HTTP_REPO_ACCESS_GITOLITE = "/usr/share/gitolite3/gitolite-shell" - - SSH_COMMAND = ( - [ - "/usr/share/gitolite3/gitolite-shell", - "%(username)s", - "%(cmd)s", - "%(reponame)s", - ], - {}, - ) - - -This ensures that the Gitolite environment is used for interacting with -Git repositories. Further customizations are listed below. - - -**gitolite 2 and 3** -~~~~~~~~~~~~~~~~~~~~ - -GITOLITE_HOME -^^^^^^^^^^^^^ - -This configuration key points to the home directory of the user under which -gitolite is ran. - - -GITOLITE_KEYDIR -^^^^^^^^^^^^^^^ - -This configuration key points to the folder where gitolite stores and accesses -the public SSH keys of all the user have access to the server. - -Since pagure is the user interface, it is pagure that writes down the files -in this directory, effectively setting up the users to be able to use gitolite. - - -GITOLITE_CONFIG -^^^^^^^^^^^^^^^ - -This configuration key points to the gitolite.conf file where pagure writes -the gitolite repository access configuration. - - -GITOLITE_CELERY_QUEUE -^^^^^^^^^^^^^^^^^^^^^ - -This configuration is useful for large pagure deployment where recompiling -the gitolite config file can take a long time. By default the compilation -of gitolite's configuration file is done by the pagure_worker, which spawns -by default 4 concurrent workers. If it takes a while to recompile the -gitolite configuration file, these workers may be stepping on each others' -toes. -In this situation, this configuration key allows you to direct the messages -asking for the gitolite configuration file to be compiled to a different -queue which can then be handled by a different service/worker. - -Pagure provides a ``pagure_gitolite_worker.service`` systemd service file -pre-configured to handles these messages if this configuration key is set -to ``gitolite_queue``. - - -**gitolite 2 only** -~~~~~~~~~~~~~~~~~~~ - -GL_RC -^^^^^ - -This configuration key points to the file ``gitolite.rc`` used by gitolite -to record who has access to what (ie: who has access to which repo/branch). - - -GL_BINDIR -^^^^^^^^^ - -This configuration key indicates the folder in which the gitolite tools can -be found. It can be as simple as ``/usr/bin/`` if the tools have been installed -using a package manager or something like ``/opt/bin/`` for a more custom -install. - - -**gitolite 3 only** -~~~~~~~~~~~~~~~~~~~ - -GITOLITE_HAS_COMPILE_1 -^^^^^^^^^^^^^^^^^^^^^^ - -By setting this configuration key to ``True``, you can turn on using the -gitolite ``compile-1`` binary. This speeds up gitolite task when it recompiles -configuration after new project is created. In order to use this, you need to -have the ``compile-1`` gitolite command. - -There are two ways to have it, - -#. You distribution already has the file installed for you and you can then - just use it. -#. You need to download and install it yourself. We are describing what - needs to be done for this here below. - -Installing the ``compile-1`` command: - -* You also have to make sure that your distribution of gitolite contains - `patch `_ - which makes gitolite respect ``ALLOW_ORPHAN_GL_CONF`` configuration variable, - if this patch isn't already present, you will have to make the change yourself. -* In your ``gitolite.rc`` set ``ALLOW_ORPHAN_GL_CONF`` to ``1`` (you may - have to add it yourself). -* Still in your ``gitolite.rc`` file, uncomment ``LOCAL_CODE`` file and set - it to a full path of a directory that you choose (for example - ``/usr/local/share/gitolite3``). -* Create a subdirectory ``commands`` under the path you picked for ``LOCAL_CODE`` - (in our example, you will need to do: ``mkdir -p /usr/local/share/gitolite3/commands``) -* Finally, install the ``compile-1`` command in this ``commands`` subdirectory - If your installation doesn't ship this file, you can `download it - `_. - (Ensure the file is executable, otherwise gitolite will not find it) - -Defaults to: ``False`` - - EventSource options ------------------- @@ -546,7 +392,7 @@ ADMIN_GROUP List of groups, either local or remote (if the openid server used supports the group extension), that are the site admins. These admins can regenerate the -gitolite configuration, the ssh key files, and the hook-token for every project +ssh key files, and the hook-token for every project as well as manage users and groups. @@ -1363,8 +1209,7 @@ ALLOW_DELETE_BRANCH This configuration keys enables or disables allowing users to delete git branches from the user interface. In sensible pagure instance you may -want to turn this off and with a customized gitolite configuration you can -prevent users from deleting branches in their git repositories. +want to turn this off. Defaults to: ``True``. @@ -1658,38 +1503,6 @@ With this configuration (evaluated in the provided order): any project on this pagure instance. -GITOLITE_PRE_CONFIG -~~~~~~~~~~~~~~~~~~~ - -This configuration key allows you to include some content at the *top* of -the gitolite configuration file (such as some specific group definition), -thus allowing to customize the gitolite configuration file with elements -and information that are outside of pagure's control. - -This can be used in combination with ``GITOLITE_POST_CONFIG`` to further -customize gitolite's configuration file. It can also be used with -``EXTERNAL_COMMITTER`` to give commit access to git repos based on external -information. - -Defaults to: ``None`` - - -GITOLITE_POST_CONFIG -~~~~~~~~~~~~~~~~~~~~ - -This configuration key allows you to include some content at the *end* of -the gitolite configuration file (such as some project definition or access), -thus allowing to customize the gitolite configuration file with elements -and information that are outside of pagure's control. - -This can be used in combination with ``GITOLITE_PRE_CONFIG`` to further -customize gitolite's configuration file. It can also be used with -``EXTERNAL_COMMITTER`` to give commit access to git repos based on external -information. - -Defaults to: ``None`` - - GIT_GARBAGE_COLLECT ~~~~~~~~~~~~~~~~~~~ @@ -1865,17 +1678,6 @@ on the webserver that sets REMOTE_USER. Defaults to: ``False`` -HTTP_REPO_ACCESS_GITOLITE -~~~~~~~~~~~~~~~~~~~~~~~~~ - -This configuration key configures the path to the gitolite-shell binary. -If this is set to None, Git http-backend is used directly. -Only set this to ``None`` if you intend to provide HTTP push access via Pagure, and -are using a dynamic ACL backend. - -Defaults to: ``/usr/share/gitolite3/gitolite-shell`` - - MIRROR_SSHKEYS_FOLDER ~~~~~~~~~~~~~~~~~~~~~ @@ -2171,23 +1973,11 @@ are available. It has been replaced by `UPLOAD_FOLDER_PATH` in the release 2.10 of pagure. -GITOLITE_VERSION -~~~~~~~~~~~~~~~~ - -This configuration key specifies which version of gitolite you are -using, it can be either ``2`` or ``3``. - -Defaults to: ``3``. - -This has been replaced by `GITOLITE_BACKEND` in the release 3.0 of pagure. - - DOCS_FOLDER, REQUESTS_FOLDER, TICKETS_FOLDER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These configuration values were removed. It has been found out that -due to how Pagure writes repo names in the gitolite configuration file, -these must have fixed paths relative to `GIT_FOLDER`. Specifically, they +These configuration values were removed. These must have +fixed paths relative to `GIT_FOLDER`. Specifically, they must occupy subdirectories `docs`, `requests` and `tickets` under `GIT_FOLDER`. They are now computed automatically based on value of `GIT_FOLDER`. Usage of docs and tickets can be triggered by setting `ENABLE_DOCS` and @@ -2243,13 +2033,6 @@ This has been deprecated by the new way of theming pagure, see the `theming documentation `_ -GITOLITE_BACKEND -~~~~~~~~~~~~~~~~ - -This configuration key allowed specifying the gitolite backend. -This has now been replaced by GIT_AUTH_BACKEND, please see that option -for information on valid values. - PAGURE_PLUGIN ~~~~~~~~~~~~~ diff --git a/doc/custom_gitolite_conf.rst b/doc/custom_gitolite_conf.rst deleted file mode 100644 index a275005..0000000 --- a/doc/custom_gitolite_conf.rst +++ /dev/null @@ -1,41 +0,0 @@ -.. _custom-gitolite: - -Customize the gitolite configuration -==================================== - -Pagure provides a mechanism to allow customizing the creation and -compilation of the configuration file of gitolite. - -To customize the gitolite configuration file, we invite you to look at the -`sources of the module pagure.lib.git_auth -`_. - -As you can see it defines the following class:: - - class GitAuthHelper(object): - - __metaclass__ = abc.ABCMeta - - @staticmethod - @abc.abstractmethod - def generate_acls(): - pass - - @classmethod - @abc.abstractmethod - def remove_acls(self, session, project): - pass - -This will be the class you will have to inherit from in order to inject your -own code. -You will then declare an entry point in your `setup.py` following this -template:: - - entry_points=""" - [pagure.git_auth.helpers] - my_git_auth = my_pagure.my_module:MyGitAuthTestHelper - """ - -Then you can adjust pagure's configuration file to say:: - - GITOLITE_BACKEND = 'my_git_auth' diff --git a/doc/index.rst b/doc/index.rst index 3b313a2..b3b37d6 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -41,7 +41,6 @@ Contents: install_crons configuration plugins - custom_gitolite_conf development contributing contributors diff --git a/doc/overview.ascii b/doc/overview.ascii index b0b9392..6a58ffe 100644 --- a/doc/overview.ascii +++ b/doc/overview.ascii @@ -6,7 +6,8 @@ Grants/Denies access | | +------------+ +-----------+ | +----------------------+ | | | | | | | | | - User's git actions +--------------------->+ Gitolite +-------------------------->+ Git repos +----+--->+ pagure logcom | | + User's git actions +--------------------->+ pagure +-------------------------->+ Git repos +----+--->+ pagure logcom | | + | auth keys | | | | | | | | | | | | +-----+------+ +---------+-+ +----------------+-----+ | ^ ^ | | diff --git a/doc/overview.rst b/doc/overview.rst index e732993..824cdad 100644 --- a/doc/overview.rst +++ b/doc/overview.rst @@ -26,8 +26,8 @@ And here is a diagram of all the components together: Pagure core application ----------------------- -The core application is the flask application interacting with gitolite to -provide a web UI to the git repositories as well as tickets and pull-requests. +The core application is the flask application and provide a web UI to +the git repositories as well as tickets and pull-requests. This is the main application for the forge. @@ -47,18 +47,6 @@ The communication between the core application and its worker is based on `_ could be used instead. -Gitolite --------- - -Currently pagure uses `gitolite `_ -to grant or deny `ssh `_ access -to the git repositories, in other words to grant or deny read and/or write -access to the git repositories. - -Pagure supports cloning over both ssh and http, but writing can only be done -via ssh, through gitolite. - - Pagure doc server ----------------- diff --git a/doc/overview_simple.ascii b/doc/overview_simple.ascii index 62fc7b0..3fa831e 100644 --- a/doc/overview_simple.ascii +++ b/doc/overview_simple.ascii @@ -2,7 +2,8 @@ Grants/Denies access +------------+ +-----------+ |cfffca4 | | | -User's git actions+--------------------->+ Gitolite +-------------------------->+ Git repos | +User's git actions+--------------------->+ pagure +-------------------------->+ Git repos | + | auth keys | | | | | | | +------------+ +-----------+ ^ ^ diff --git a/doc/usage/first_steps.rst b/doc/usage/first_steps.rst index d3d5ec8..c68bae1 100644 --- a/doc/usage/first_steps.rst +++ b/doc/usage/first_steps.rst @@ -29,9 +29,6 @@ account. Upload your SSH key ------------------- -Pagure uses gitolite to manage who has read/write access to which git -repository via `ssh `_. - An ssh key is composed of two parts: * a private key, which you must keep to yourself and never share with anyone. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 693fef4..dba148c 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -42,7 +42,6 @@ Contents: first_steps forks - read_only http_push pull_requests markdown diff --git a/doc/usage/read_only.rst b/doc/usage/read_only.rst deleted file mode 100644 index f095f53..0000000 --- a/doc/usage/read_only.rst +++ /dev/null @@ -1,33 +0,0 @@ -Understanding Read Only Mode of projects -========================================= - -If a project is in Read Only Mode, the users of the project may not be -able to modify the git repository of the project. Let's say you forked -a project, then the forked project goes into a read only mode. You won't -be able to modify the git repository of the forked project in that mode. -After the read only mode is gone, you can begin to use the git repository -again. Let's say you decide to add another user to your fork, this time -the project will go in read only mode again but, you still will be able -to use the git repository while the new user will have to wait for read -only mode to get over. This is also true when you remove a user from your -project. The removed user can still access the project's git repository, -given that he had at least commit access, until the read only mode is over. - -In Pagure, we use gitolite for Access Control Lists when using SSH. -Modifying gitolite may be a time taking task (depending on number of projects -hosted on the pagure instance) that's why Pagure does it outside of HTTP -Request-Response Cycle. - -Whenever you fork a project or add/remove a new user/group to project, -gitolite needs to be refreshed in order to put those changes in effect -for ssh based git usage. - - -Actions that put the project in read only mode ----------------------------------------------- - -All the actions that needs gitolite to be compiled, will bring the -project in read only mode. - -* Creating/Forking a project. (only the fork will be in read only mode) -* Adding/Removing a user/group from a project. diff --git a/files/gitolite.rc b/files/gitolite.rc deleted file mode 100755 index b5fbf31..0000000 --- a/files/gitolite.rc +++ /dev/null @@ -1,233 +0,0 @@ -# paths and configuration variables for gitolite - -# please read comments before editing - -# this file is meant to be pulled into a perl program using "do" or "require". - -# You do NOT need to know perl to edit the paths; it should be fairly -# self-explanatory and easy to maintain perl syntax :-) - -# -------------------------------------- -# Do not uncomment these values unless you know what you're doing -# $GL_PACKAGE_CONF = ""; -# $GL_PACKAGE_HOOKS = ""; - -# -------------------------------------- - -# -------------------------------------- - -# this is where the repos go. If you provide a relative path (not starting -# with "/"), it's relative to your $HOME. You may want to put in something -# like "/bigdisk" or whatever if your $HOME is too small for the repos, for -# example - -$REPO_BASE="/path/to/git/repositories/"; - -# the default umask for repositories is 0077; change this if you run stuff -# like gitweb and find it can't read the repos. Please note the syntax; the -# leading 0 is required - -$REPO_UMASK = 0002; -# $REPO_UMASK = 0027; # gets you 'rwxr-x---' -# $REPO_UMASK = 0022; # gets you 'rwxr-xr-x' - -# part of the setup of gitweb is a variable called $projects_list (please see -# gitweb documentation for more on this). Set this to the same value: - -$PROJECTS_LIST = $ENV{HOME} . "/projects.list"; - -# -------------------------------------- - -# I see no reason anyone may want to change the gitolite admin directory, but -# feel free to do so. However, please note that it *must* be an *absolute* -# path (i.e., starting with a "/" character) - -# gitolite admin directory, files, etc - -$GL_ADMINDIR="/etc/gitolite"; - -# -------------------------------------- - -# templates for location of the log files and format of their names - -# I prefer this template (note the %y and %m placeholders) -# it produces files like `~/.gitolite/logs/gitolite-2009-09.log` - -$GL_LOGT="/var/log/gitolite/gitolite-%y-%m.log"; - -# other choices are below, or you can make your own -- but PLEASE MAKE SURE -# the directory exists and is writable; gitolite won't do that for you (unless -# it is the default, which is "$GL_ADMINDIR/logs") - -# $GL_LOGT="$GL_ADMINDIR/logs/gitolite-%y-%m-%d.log"; -# $GL_LOGT="$GL_ADMINDIR/logs/gitolite-%y.log"; - -# -------------------------------------- - -# Please DO NOT change these three paths - -$GL_CONF="$GL_ADMINDIR/conf/gitolite.conf"; -$GL_KEYDIR="$GL_ADMINDIR/keydir"; -$GL_CONF_COMPILED="$GL_ADMINDIR/conf/gitolite.conf-compiled.pm"; - -# -------------------------------------- - -# if git on your server is on a standard path (that is -# ssh git@server git --version -# works), leave this setting as is. Otherwise, choose one of the -# alternatives, or write your own - -$GIT_PATH=""; -# $GIT_PATH="/opt/bin/"; - -# -------------------------------------- - -# ---------------------------------------------------------------------- -# BIG CONFIG SETTINGS - -# Please read doc/big-config.mkd for details - -$GL_BIG_CONFIG = 1; -$GL_NO_DAEMON_NO_GITWEB = 1; -$GL_NO_CREATE_REPOS = 1; -$GL_NO_SETUP_AUTHKEYS = 1; - - -# ---------------------------------------------------------------------- -# SECURITY SENSITIVE SETTINGS -# -# Settings below this point may have security implications. That -# usually means that I have not thought hard enough about all the -# possible ways to crack security if these settings are enabled. - -# Please see details on each setting for specifics, if any. -# ---------------------------------------------------------------------- - - - -# -------------------------------------- -# ALLOW REPO ADMIN TO SET GITCONFIG KEYS -# -# Gitolite allows you to set git repo options using the "config" keyword; see -# conf/example.conf for details and syntax. -# -# However, if you are in an installation where the repo admin does not (and -# should not) have shell access to the server, then allowing him to set -# arbitrary repo config options *may* be a security risk -- some config -# settings may allow executing arbitrary commands. -# -# You have 3 choices. By default $GL_GITCONFIG_KEYS is left empty, which -# completely disables this feature (meaning you cannot set git configs from -# the repo config). - -$GL_GITCONFIG_KEYS = ""; - -# The second choice is to give it a space separated list of settings you -# consider safe. (These are actually treated as a set of regular expression -# patterns, and any one of them must match). For example: -# $GL_GITCONFIG_KEYS = "core\.logAllRefUpdates core\..*compression"; -# allows repo admins to set one of those 3 config keys (yes, that second -# pattern matches two settings from "man git-config", if you look) -# -# The third choice (which you may have guessed already if you're familiar with -# regular expressions) is to allow anything and everything: -# $GL_GITCONFIG_KEYS = ".*"; - -# -------------------------------------- -# EXTERNAL COMMAND HELPER -- HTPASSWD - -# security note: runs an external command (htpasswd) with specific arguments, -# including a user-chosen "password". - -# if you want to enable the "htpasswd" command, give this the absolute path to -# whatever file apache (etc) expect to find the passwords in. - -$HTPASSWD_FILE = ""; - -# Look in doc/3 ("easier to link gitweb authorisation with gitolite" section) -# for more details on using this feature. - -# -------------------------------------- -# EXTERNAL COMMAND HELPER -- RSYNC - -# security note: runs an external command (rsync) with specific arguments, all -# presumably filled in correctly by the client-side rsync. - -# base path of all the files that are accessible via rsync. Must be an -# absolute path. Leave it undefined or set to the empty string to disable the -# rsync helper. - -$RSYNC_BASE = ""; - -# $RSYNC_BASE = "/home/git/up-down"; -# $RSYNC_BASE = "/tmp/up-down"; - -# -------------------------------------- -# EXTERNAL COMMAND HELPER -- SVNSERVE - -# security note: runs an external command (svnserve) with specific arguments, -# as specified below. %u is substituted with the username. - -# This setting allows launching svnserve when requested by the ssh client. -# This allows using the same SSH setup (hostname/username/public key) for both -# SVN and git access. Leave it undefined or set to the empty string to disable -# svnserve access. - -$SVNSERVE = ""; -# $SVNSERVE = "/usr/bin/svnserve -r /var/svn/ -t --tunnel-user=%u"; - -# -------------------------------------- -# ALLOW REPO CONFIG TO USE WILDCARDS - -# security note: this used to in a separate "wildrepos" branch. You can -# create repositories based on wild cards, give "ownership" to the specific -# user who created it, allow him/her to hand out R and RW permissions to other -# users to collaborate, etc. This is powerful stuff, and I've made it as -# secure as I can, but it hasn't had the kind of rigorous line-by-line -# analysis that the old "master" branch had. - -# This has now been rolled into master, with all the functionality gated by -# this variable. Set this to 1 if you want to enable the wildrepos features. -# Please see doc/4-wildcard-repositories.mkd for details. - -$GL_WILDREPOS = 0; - -# -------------------------------------- -# DEFAULT WILDCARD PERMISSIONS - -# If set, this value will be used as the default user-level permission rule of -# new wildcard repositories. The user can change this value with the setperms command -# as desired after repository creation; it is only a default. Note that @all can be -# used here but is special; no other groups can be used in user-level permissions. - -# $GL_WILDREPOS_DEFPERMS = 'R = @all'; - -# -------------------------------------- -# HOOK CHAINING - -# by default, the update hook in every repo chains to "update.secondary". -# Similarly, the post-update hook in the admin repo chains to -# "post-update.secondary". If you're fine with the defaults, there's no need -# to do anything here. However, if you want to use different names or paths, -# change these variables - -# $UPDATE_CHAINS_TO = "hooks/update.secondary"; -# $ADMIN_POST_UPDATE_CHAINS_TO = "hooks/post-update.secondary"; - -# -------------------------------------- -# ADMIN DEFINED COMMANDS - -# WARNING: Use this feature only if (a) you really really know what you're -# doing or (b) you really don't care too much about security. Please read -# doc/admin-defined-commands.mkd for details. - -# $GL_ADC_PATH = ""; - -# -------------------------------------- -# per perl rules, this should be the last line in such a file: -1; - -# Local variables: -# mode: perl -# End: -# vim: set syn=perl: diff --git a/files/gitolite3.rc b/files/gitolite3.rc deleted file mode 100644 index 8b7147f..0000000 --- a/files/gitolite3.rc +++ /dev/null @@ -1,197 +0,0 @@ -# configuration variables for gitolite - -# This file is in perl syntax. But you do NOT need to know perl to edit it -- -# just mind the commas, use single quotes unless you know what you're doing, -# and make sure the brackets and braces stay matched up! - -# (Tip: perl allows a comma after the last item in a list also!) - -# HELP for commands can be had by running the command with "-h". - -# HELP for all the other FEATURES can be found in the documentation (look for -# "list of non-core programs shipped with gitolite" in the master index) or -# directly in the corresponding source file. - -%RC = ( - - # ------------------------------------------------------------------ - - GL_REPO_BASE => '/path/to/git/repositories', - - # default umask gives you perms of '0700'; see the rc file docs for - # how/why you might change this - UMASK => 0077, - - # look for "git-config" in the documentation - GIT_CONFIG_KEYS => '', - - # comment out if you don't need all the extra detail in the logfile - LOG_EXTRA => 1, - # syslog options - # 1. leave this section as is for normal gitolite logging - # 2. uncomment this line to log only to syslog: - # LOG_DEST => 'syslog', - # 3. uncomment this line to log to syslog and the normal gitolite log: - # LOG_DEST => 'syslog,normal', - - # roles. add more roles (like MANAGER, TESTER, ...) here. - # WARNING: if you make changes to this hash, you MUST run 'gitolite - # compile' afterward, and possibly also 'gitolite trigger POST_COMPILE' - ROLES => { - READERS => 1, - WRITERS => 1, - }, - - # enable caching (currently only Redis). PLEASE RTFM BEFORE USING!!! - # CACHE => 'Redis', - - # ------------------------------------------------------------------ - - # rc variables used by various features - - # the 'info' command prints this as additional info, if it is set - # SITE_INFO => 'Please see http://blahblah/gitolite for more help', - - # the CpuTime feature uses these - # display user, system, and elapsed times to user after each git operation - # DISPLAY_CPU_TIME => 1, - # display a warning if total CPU times (u, s, cu, cs) crosses this limit - # CPU_TIME_WARN_LIMIT => 0.1, - - # the Mirroring feature needs this - # HOSTNAME => "foo", - - # TTL for redis cache; PLEASE SEE DOCUMENTATION BEFORE UNCOMMENTING! - # CACHE_TTL => 600, - - # ------------------------------------------------------------------ - - # suggested locations for site-local gitolite code (see cust.html) - - # this one is managed directly on the server - # LOCAL_CODE => "$ENV{HOME}/local", - - # or you can use this, which lets you put everything in a subdirectory - # called "local" in your gitolite-admin repo. For a SECURITY WARNING - # on this, see http://gitolite.com/gitolite/non-core.html#pushcode - # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local", - - # ------------------------------------------------------------------ - - # List of commands and features to enable - - ENABLE => [ - - # COMMANDS - - # These are the commands enabled by default - 'help', - 'desc', - 'info', - 'perms', - 'writable', - - # Uncomment or add new commands here. - # 'create', - # 'fork', - # 'mirror', - # 'readme', - # 'sskm', - # 'D', - - # These FEATURES are enabled by default. - - # essential (unless you're using smart-http mode) - 'ssh-authkeys', - - # creates git-config enties from gitolite.conf file entries like 'config foo.bar = baz' - 'git-config', - - # creates git-daemon-export-ok files; if you don't use git-daemon, comment this out - 'daemon', - - # creates projects.list file; if you don't use gitweb, comment this out - #'gitweb', - - # These FEATURES are disabled by default; uncomment to enable. If you - # need to add new ones, ask on the mailing list :-) - - # user-visible behaviour - - # prevent wild repos auto-create on fetch/clone - # 'no-create-on-read', - # no auto-create at all (don't forget to enable the 'create' command!) - # 'no-auto-create', - - # access a repo by another (possibly legacy) name - # 'Alias', - - # give some users direct shell access. See documentation in - # sts.html for details on the following two choices. - # "Shell $ENV{HOME}/.gitolite.shell-users", - # 'Shell alice bob', - - # set default roles from lines like 'option default.roles-1 = ...', etc. - # 'set-default-roles', - - # show more detailed messages on deny - # 'expand-deny-messages', - - # show a message of the day - # 'Motd', - - # system admin stuff - - # enable mirroring (don't forget to set the HOSTNAME too!) - # 'Mirroring', - - # allow people to submit pub files with more than one key in them - # 'ssh-authkeys-split', - - # selective read control hack - # 'partial-copy', - - # manage local, gitolite-controlled, copies of read-only upstream repos - # 'upstream', - - # updates 'description' file instead of 'gitweb.description' config item - # 'cgit', - - # allow repo-specific hooks to be added - # 'repo-specific-hooks', - - # performance, logging, monitoring... - - # be nice - # 'renice 10', - - # log CPU times (user, system, cumulative user, cumulative system) - # 'CpuTime', - - # syntactic_sugar for gitolite.conf and included files - - # allow backslash-escaped continuation lines in gitolite.conf - # 'continuation-lines', - - # create implicit user groups from directory names in keydir/ - # 'keysubdirs-as-groups', - - # allow simple line-oriented macros - # 'macros', - - # Kindergarten mode - - # disallow various things that sensible people shouldn't be doing anyway - # 'Kindergarten', - ], - -); - -# ------------------------------------------------------------------------------ -# per perl rules, this should be the last line in such a file: -1; - -# Local variables: -# mode: perl -# End: -# vim: set syn=perl: diff --git a/files/pagure.cfg.sample b/files/pagure.cfg.sample index f7c654e..df7bcf8 100644 --- a/files/pagure.cfg.sample +++ b/files/pagure.cfg.sample @@ -99,31 +99,6 @@ REMOTE_GIT_FOLDER = os.path.join( VIRUS_SCAN_ATTACHMENTS = False -### Configuration file for gitolite -GITOLITE_CONFIG = os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'gitolite.conf' -) - - -### Home folder of the gitolite user -### Folder where to run gl-compile-conf from -GITOLITE_HOME = None - -### Version of gitolite used: 2 or 3? -GITOLITE_VERSION = 3 - -### Folder containing all the public ssh keys for gitolite -GITOLITE_KEYDIR = None - -### Path to the gitolite.rc file -GL_RC = None - -### Path to the /bin directory where the gitolite tools can be found -GL_BINDIR = None - - # SSH Information ### SSH commend for interacting with repositories diff --git a/files/pagure.spec b/files/pagure.spec index 5ae9444..16c84b8 100644 --- a/files/pagure.spec +++ b/files/pagure.spec @@ -268,10 +268,6 @@ mkdir -p $RPM_BUILD_ROOT/%{_unitdir} install -p -m 644 files/pagure_worker.service \ $RPM_BUILD_ROOT/%{_unitdir}/pagure_worker.service -# Install the systemd file for the gitolite worker -install -p -m 644 files/pagure_gitolite_worker.service \ - $RPM_BUILD_ROOT/%{_unitdir}/pagure_gitolite_worker.service - # Install the systemd file for the web-hook install -p -m 644 files/pagure_webhook.service \ $RPM_BUILD_ROOT/%{_unitdir}/pagure_webhook.service @@ -365,7 +361,6 @@ done %post %systemd_post pagure_worker.service -%systemd_post pagure_gitolite_worker.service %systemd_post pagure_api_key_expire_mail.timer %systemd_post pagure_mirror_project_in.timer %post web-nginx @@ -388,7 +383,6 @@ done %preun %systemd_preun pagure_worker.service -%systemd_preun pagure_gitolite_worker.service %systemd_preun pagure_api_key_expire_mail.timer %systemd_preun pagure_mirror_project_in.timer %preun web-nginx @@ -411,7 +405,6 @@ done %postun %systemd_postun_with_restart pagure_worker.service -%systemd_postun_with_restart pagure_gitolite_worker.service %systemd_postun pagure_api_key_expire_mail.timer %systemd_postun pagure_mirror_project_in.timer %postun web-nginx @@ -451,7 +444,6 @@ done %{python_sitelib}/pagure*.egg-info %{_bindir}/pagure-admin %{_unitdir}/pagure_worker.service -%{_unitdir}/pagure_gitolite_worker.service %{_unitdir}/pagure_api_key_expire_mail.service %{_unitdir}/pagure_api_key_expire_mail.timer %{_unitdir}/pagure_mirror_project_in.service diff --git a/files/pagure_gitolite_worker.service b/files/pagure_gitolite_worker.service deleted file mode 100644 index 5f9bb02..0000000 --- a/files/pagure_gitolite_worker.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Pagure worker for backend git interaction -After=redis.target -Documentation=https://pagure.io/pagure - -[Service] -ExecStart=/usr/bin/celery -A pagure.lib.tasks worker --loglevel=INFO -c 1 -Q gitolite_queue -n gitolite -Environment="PAGURE_CONFIG=/etc/pagure/pagure.cfg" -Type=simple -User=git -Group=git -Restart=on-failure - -[Install] -WantedBy=multi-user.target diff --git a/files/pagure_worker.service.example b/files/pagure_worker.service.example index 0195f5e..c7628f6 100644 --- a/files/pagure_worker.service.example +++ b/files/pagure_worker.service.example @@ -5,7 +5,7 @@ # FAST_CELERY_QUEUE, MEDIUM_CELERY_QUEUE or SLOW_CELERY_QUEUE [Unit] -Description=Pagure worker for gitolite interactions +Description=Pagure worker After=redis.target Documentation=https://pagure.io/pagure diff --git a/pagure/api/__init__.py b/pagure/api/__init__.py index 14486f0..25f0417 100644 --- a/pagure/api/__init__.py +++ b/pagure/api/__init__.py @@ -547,7 +547,6 @@ def api(): project.api_new_branch, project.api_fork_project, project.api_modify_acls, - project.api_generate_acls, project.api_commit_flags, project.api_commit_add_flag, project.api_update_project_watchers, diff --git a/pagure/api/group.py b/pagure/api/group.py index dcb687f..1e82d21 100644 --- a/pagure/api/group.py +++ b/pagure/api/group.py @@ -365,9 +365,6 @@ def api_group_add_member(group): is_admin=pagure.utils.is_admin(), ) flask.g.session.commit() - pagure.lib.git.generate_gitolite_acls( - project=None, group=group.group_name - ) except (pagure.exceptions.PagureException, SQLAlchemyError) as err: flask.g.session.rollback() raise pagure.exceptions.APIError( @@ -453,9 +450,6 @@ def api_group_remove_member(group): is_admin=pagure.utils.is_admin(), ) flask.g.session.commit() - pagure.lib.git.generate_gitolite_acls( - project=None, group=group.group_name - ) except (pagure.exceptions.PagureException, SQLAlchemyError) as err: flask.g.session.rollback() raise pagure.exceptions.APIError( diff --git a/pagure/api/project.py b/pagure/api/project.py index 52bf413..d2db558 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -1674,8 +1674,6 @@ def api_modify_project(repo, namespace=None): flask.g.session.rollback() raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR) - pagure.lib.git.generate_gitolite_acls(project=project) - return flask.jsonify(project.to_json(public=False, api=True)) @@ -1784,83 +1782,6 @@ def api_fork_project(): return jsonout -@API.route("//git/generateacls", methods=["POST"]) -@API.route("///git/generateacls", methods=["POST"]) -@API.route("/fork///git/generateacls", methods=["POST"]) -@API.route( - "/fork////git/generateacls", methods=["POST"] -) -@api_login_required(acls=["generate_acls_project"]) -@api_method -def api_generate_acls(repo, username=None, namespace=None): - """ - Generate Gitolite ACLs on a project - ----------------------------------- - Generate Gitolite ACLs on a project. This is restricted to Pagure admins. - - This is an asynchronous call. - - :: - - POST /api/0/rpms/python-requests/git/generateacls - - - Input - ^^^^^ - - +------------------+---------+--------------+---------------------------+ - | Key | Type | Optionality | Description | - +==================+=========+==============+===========================+ - | ``wait`` | boolean | Optional | | A boolean to specify if | - | | | | this API call should | - | | | | return a taskid or if it| - | | | | should wait for the task| - | | | | to finish. | - +------------------+---------+--------------+---------------------------+ - - - Sample response - ^^^^^^^^^^^^^^^ - - :: - - wait=False: - { - 'message': 'Project ACL generation queued', - 'taskid': '123-abcd' - } - - wait=True: - { - 'message': 'Project ACLs generated' - } - - """ - project = _get_repo(repo, username, namespace) - _check_token(project, project_token=False) - - wait = pagure.utils.is_true(get_request_data().get("wait")) - - try: - task = pagure.lib.git.generate_gitolite_acls(project=project) - - if wait: - task.get() - output = {"message": "Project ACLs generated"} - else: - output = { - "message": "Project ACL generation queued", - "taskid": task.id, - } - except pagure.exceptions.PagureException as err: - raise pagure.exceptions.APIError( - 400, error_code=APIERROR.ENOCODE, error=str(err) - ) - - jsonout = flask.jsonify(output) - return jsonout - - @API.route("//git/branch", methods=["POST"]) @API.route("///git/branch", methods=["POST"]) @API.route("/fork///git/branch", methods=["POST"]) @@ -2807,10 +2728,6 @@ def api_modify_acls(repo, namespace=None, username=None): if grp.id == group_obj.id: project.groups.remove(grp) break - pagure.lib.query.update_read_only_mode( - flask.g.session, project, read_only=True - ) - pagure.lib.git.generate_gitolite_acls(project=project) try: flask.g.session.commit() @@ -2823,7 +2740,6 @@ def api_modify_acls(repo, namespace=None, username=None): flask.g.session.rollback() raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR) - pagure.lib.git.generate_gitolite_acls(project=project) output = project.to_json(api=True, public=True) else: raise pagure.exceptions.APIError( @@ -3500,16 +3416,6 @@ def delete_project(repo, username=None, namespace=None): 401, error_code=APIERROR.ENOTHIGHENOUGH ) - if project.read_only: - error = ( - "The ACLs of this project are being refreshed in the backend " - "this prevents the project from being deleted. Please wait " - "for this task to finish before trying again. Thanks!" - ) - raise pagure.exceptions.APIError( - 400, error_code=APIERROR.ENOCODE, error=error - ) - project_json = project.to_json(public=True, api=True) pagure.lib.tasks.delete_project( diff --git a/pagure/cli/admin.py b/pagure/cli/admin.py index 70d862c..c8a7834 100644 --- a/pagure/cli/admin.py +++ b/pagure/cli/admin.py @@ -33,7 +33,6 @@ import pagure.lib.model # noqa: E402 import pagure.lib.model_base # noqa: E402 import pagure.lib.query # noqa: E402 import pagure.lib.tasks_utils # noqa: E402 -from pagure.flask_app import generate_user_key_files # noqa: E402 from pagure.utils import get_repo_path # noqa: E402 _config = pagure.config.reload_config() @@ -50,49 +49,6 @@ WATCH = { } -def _parser_refresh_gitolite(subparser): - """Set up the CLI argument parser for the refresh-gitolite action. - - :arg subparser: an argparse subparser allowing to have action's specific - arguments - - """ - local_parser = subparser.add_parser( - "refresh-gitolite", help="Re-generate the gitolite config file" - ) - local_parser.add_argument( - "--user", help="User of the project (to use only on forks)" - ) - local_parser.add_argument( - "--project", - help="Project to update (as namespace/project if there " - "is a namespace)", - ) - local_parser.add_argument("--group", help="Group to refresh") - local_parser.add_argument( - "--all", - dest="all_", - default=False, - action="store_true", - help="Refresh all the projects", - ) - local_parser.set_defaults(func=do_generate_acl) - - -def _parser_refresh_ssh(subparser): - """Set up the CLI argument parser for the refresh-ssh action. - - :arg subparser: an argparse subparser allowing to have action's specific - arguments - - """ - local_parser = subparser.add_parser( - "refresh-ssh", - help="Re-write to disk every user's ssh key stored in the database", - ) - local_parser.set_defaults(func=do_refresh_ssh) - - def _parser_clear_hook_token(subparser): """Set up the CLI argument parser for the clear-hook-token action. @@ -287,32 +243,6 @@ def _parser_update_watch(subparser): local_parser.set_defaults(func=do_update_watch_status) -def _parser_read_only(subparser): - """Set up the CLI argument parser for the read-only action. - - :arg subparser: an argparse subparser allowing to have action's specific - arguments - - """ - local_parser = subparser.add_parser( - "read-only", help="Get or set the read-only flag on a project" - ) - local_parser.add_argument( - "--user", help="User of the project (to use only on forks)" - ) - local_parser.add_argument( - "project", - help="Project to update (as namespace/project if there " - "is a namespace)", - ) - local_parser.add_argument( - "--ro", - help="Read-Only status to set (has to be: true or false), do not " - "specify to get the current status", - ) - local_parser.set_defaults(func=do_read_only) - - def _parser_new_group(subparser): """Set up the CLI argument parser for the new-group action. @@ -543,12 +473,6 @@ def parse_arguments(args=None): subparser = parser.add_subparsers(title="actions") - # refresh-gitolite - _parser_refresh_gitolite(subparser) - - # refresh-ssh - _parser_refresh_ssh(subparser) - # clear-hook-token _parser_clear_hook_token(subparser) @@ -561,9 +485,6 @@ def parse_arguments(args=None): # update-watch _parser_update_watch(subparser) - # read-only - _parser_read_only(subparser) - # new-group _parser_new_group(subparser) @@ -634,78 +555,6 @@ def _check_project(_project, **kwargs): ) -def do_generate_acl(args): - """Regenerate the gitolite ACL file. - - - :arg args: the argparse object returned by ``parse_arguments()``. - - """ - _log.debug("group: %s", args.group) - _log.debug("project: %s", args.project) - _log.debug("user: %s", args.user) - _log.debug("all: %s", args.all_) - - title = None - project = None - if args.project: - project = _get_project(args.project, user=args.user) - title = project.fullname - if args.all_: - title = "all" - project = -1 - - if not args.all_ and not args.project: - print( - "Please note that you have not selected a project or --all. " - "Do you want to recompile the existing config file?" - ) - if not _ask_confirmation(): - return - - helper = pagure.lib.git_auth.get_git_auth_helper() - _log.debug("Got helper: %s", helper) - - group_obj = None - if args.group: - group_obj = pagure.lib.query.search_groups( - session, group_name=args.group - ) - _log.debug( - "Calling helper: %s with arg: project=%s, group=%s", - helper, - project, - group_obj, - ) - - print( - "Do you want to re-generate the gitolite.conf file for group: %s " - "and project: %s?" % (group_obj, title) - ) - if _ask_confirmation(): - helper.generate_acls(project=project, group=group_obj) - pagure.lib.tasks_utils.gc_clean() - print("Gitolite ACLs updated") - - -def do_refresh_ssh(_): - """Regenerate the user key files. - - :arg _: the argparse object returned by ``parse_arguments()``, which is - ignored as there are no argument to pass to this action. - - """ - print( - "Do you want to re-generate all the ssh keys for every user in " - "the database? (Depending on your instance this may take a while " - "and result in an outage while it lasts)" - ) - if _ask_confirmation(): - generate_user_key_files() - print("User key files regenerated") - do_generate_acl() - - def do_generate_hook_token(_): """Regenerate the hook_token for each projects in the DB. @@ -1173,48 +1022,6 @@ def do_update_watch_status(args): session.commit() -def do_read_only(args): - """Set or update the read-only status of a project. - - :arg args: the argparse object returned by ``parse_arguments()``. - - """ - - _log.debug("project: %s", args.project) - _log.debug("user: %s", args.user) - _log.debug("read-only: %s", args.ro) - - # Validate user - pagure.lib.query.get_user(session, args.user) - - # Get the project - project = _get_project(args.project, user=args.user) - - _check_project(project, project=args.project) - - # Validate ro flag - if args.ro and args.ro.lower() not in ["true", "false"]: - raise pagure.exceptions.PagureException( - "Invalid read-only status specified: %s is not in: " - "true, false" % args.ro.lower() - ) - - if not args.ro: - print( - "The current read-only flag of the project %s is set to %s" - % (project.fullname, project.read_only) - ) - else: - pagure.lib.query.update_read_only_mode( - session, project, read_only=(args.ro.lower() == "true") - ) - session.commit() - print( - "The read-only flag of the project %s has been set to %s" - % (project.fullname, args.ro.lower() == "true") - ) - - def do_new_group(args): """Create a new group in this pagure instance. diff --git a/pagure/config.py b/pagure/config.py index 79714e9..067e012 100644 --- a/pagure/config.py +++ b/pagure/config.py @@ -39,10 +39,6 @@ def reload_config(): ) config["REQUESTS_FOLDER"] = os.path.join(config["GIT_FOLDER"], "requests") - if "GITOLITE_BACKEND" in config: - # This is for backwards compatibility purposes - config["GIT_AUTH_BACKEND"] = config["GITOLITE_BACKEND"] - return config diff --git a/pagure/default_config.py b/pagure/default_config.py index b3e3996..ec8ae2a 100644 --- a/pagure/default_config.py +++ b/pagure/default_config.py @@ -158,7 +158,6 @@ SSH_FOLDER = os.path.join( ) # Folder containing to the git repos -# Note that this must be exactly the same as GL_REPO_BASE in gitolite.rc GIT_FOLDER = os.path.join( os.path.abspath(os.path.dirname(__file__)), "..", "lcl", "repos" ) @@ -176,46 +175,15 @@ ATTACHMENTS_FOLDER = os.path.join( # Whether to enable scanning for viruses in attachments VIRUS_SCAN_ATTACHMENTS = False -# Configuration file for gitolite -GITOLITE_CONFIG = os.path.join( - os.path.abspath(os.path.dirname(__file__)), "..", "lcl", "gitolite.conf" -) - # Configuration keys to specify where the upload folder is and what is its # name UPLOAD_FOLDER_PATH = os.path.join( os.path.abspath(os.path.dirname(__file__)), "..", "lcl", "releases" ) - -# Home folder of the gitolite user -- Folder where to run gl-compile-conf from -GITOLITE_HOME = None - -# Version of gitolite used: 2 or 3? -GITOLITE_VERSION = 3 - -# Folder containing all the public ssh keys for gitolite -GITOLITE_KEYDIR = None - # Backend for git auth decisions -# This may be either a static helper (like gitolite based) or dynamic. GIT_AUTH_BACKEND = "pagure_authorized_keys" -# Legacy option name for GIT_AUTH_BACKEND, retained for backwards compatibility -# This option overrides GIT_AUTH_BACKEND -# GITOLITE_BACKEND = "gitolite3" - -# Whether or not this installation of Pagure should use `gitolite compile-1` -# to improve speed of some gitolite operations. See documentation for more -# info about how to set this up. -GITOLITE_HAS_COMPILE_1 = False - -# Path to the gitolite.rc file -GL_RC = None -# Path to the /bin directory where the gitolite tools can be found -GL_BINDIR = None - - # Whether or not to run "git gc --auto" after every change to a project # This will use default git config values # See https://git-scm.com/docs/git-gc#git-gc---auto for more details @@ -337,7 +305,6 @@ ACLS = { "create_project": "Create a new project", "commit_flag": "Flag a commit", "fork_project": "Fork a project", - "generate_acls_project": "Generate the Gitolite ACLs on a project", "internal_access": "Access Pagure's internal APIs", "issue_assign": "Assign issue to someone", "issue_change_status": "Change the status of a ticket", @@ -372,11 +339,7 @@ ACLS = { # List of ACLs which a regular user is allowed to associate to an API token # from the ACLs above -USER_ACLS = [ - key - for key in ACLS.keys() - if key not in ["generate_acls_project", "internal_access"] -] +USER_ACLS = [key for key in ACLS.keys() if key not in ["internal_access"]] # From the ACLs above lists which ones are tolerated to be associated with # an API token that isn't linked to a particular project. @@ -400,7 +363,6 @@ ADMIN_API_ACLS = [ "pull_request_flag", "pull_request_comment", "pull_request_merge", - "generate_acls_project", "group_modify", "commit_flag", "create_branch", @@ -566,8 +528,6 @@ _REACTIONS_DICT = dict(REACTIONS) ALLOW_HTTP_PULL_PUSH = True # Whether to allow pushing via HTTP ALLOW_HTTP_PUSH = False -# Path to Gitolite-shell if using that, None to use Git directly -HTTP_REPO_ACCESS_GITOLITE = None # Configuration for the key helper # Look a username up in the database, overrides SSH_KEYS_USERNAME_EXPECT diff --git a/pagure/flask_app.py b/pagure/flask_app.py index 50a9ac6..3481e95 100644 --- a/pagure/flask_app.py +++ b/pagure/flask_app.py @@ -222,22 +222,6 @@ def create_app(config=None): return app -def generate_user_key_files(): - """Regenerate the key files used by gitolite.""" - gitolite_home = pagure_config.get("GITOLITE_HOME", None) - if gitolite_home: - users = pagure.lib.query.search_user(flask.g.session) - for user in users: - pagure.lib.query.update_user_ssh( - flask.g.session, - user, - None, - pagure_config.get("GITOLITE_KEYDIR", None), - update_only=True, - ) - pagure.lib.git.generate_gitolite_acls(project=None) - - def admin_session_timedout(): """Check if the current user has been authenticated for more than what is allowed (defaults to 15 minutes). diff --git a/pagure/hooks/files/git_multimail_upstream.py b/pagure/hooks/files/git_multimail_upstream.py index 346c2a8..14b8911 100755 --- a/pagure/hooks/files/git_multimail_upstream.py +++ b/pagure/hooks/files/git_multimail_upstream.py @@ -3335,67 +3335,6 @@ class GenericEnvironmentMixin(Environment): ) -class GitoliteEnvironmentHighPrecMixin(Environment): - def get_pusher(self): - return self.osenv.get("GL_USER", "unknown user") - - -class GitoliteEnvironmentLowPrecMixin(Environment): - def get_repo_shortname(self): - # The gitolite environment variable $GL_REPO is a pretty good - # repo_shortname (though it's probably not as good as a value - # the user might have explicitly put in his config). - return ( - self.osenv.get("GL_REPO", None) - or super( - GitoliteEnvironmentLowPrecMixin, self - ).get_repo_shortname() - ) - - def get_fromaddr(self, change=None): - GL_USER = self.osenv.get("GL_USER") - if GL_USER is not None: - # Find the path to gitolite.conf. Note that gitolite v3 - # did away with the GL_ADMINDIR and GL_CONF environment - # variables (they are now hard-coded). - GL_ADMINDIR = self.osenv.get( - "GL_ADMINDIR", - os.path.expanduser(os.path.join("~", ".gitolite")), - ) - GL_CONF = self.osenv.get( - "GL_CONF", os.path.join(GL_ADMINDIR, "conf", "gitolite.conf") - ) - if os.path.isfile(GL_CONF): - f = open(GL_CONF, "rU") - try: - in_user_emails_section = False - re_template = r"^\s*#\s*%s\s*$" - re_begin, re_user, re_end = ( - re.compile(re_template % x) - for x in ( - r"BEGIN\s+USER\s+EMAILS", - re.escape(GL_USER) + r"\s+(.*)", - r"END\s+USER\s+EMAILS", - ) - ) - for l in f: - l = l.rstrip("\n") - if not in_user_emails_section: - if re_begin.match(l): - in_user_emails_section = True - continue - if re_end.match(l): - break - m = re_user.match(l) - if m: - return m.group(1) - finally: - f.close() - return super(GitoliteEnvironmentLowPrecMixin, self).get_fromaddr( - change - ) - - class IncrementalDateTime(object): """Simple wrapper to give incremental date/times. @@ -4063,10 +4002,6 @@ def choose_mailer(config, environment): KNOWN_ENVIRONMENTS = { "generic": {"highprec": GenericEnvironmentMixin}, - "gitolite": { - "highprec": GitoliteEnvironmentHighPrecMixin, - "lowprec": GitoliteEnvironmentLowPrecMixin, - }, "stash": { "highprec": StashEnvironmentHighPrecMixin, "lowprec": StashEnvironmentLowPrecMixin, @@ -4097,10 +4032,7 @@ def choose_environment_name(config, env, osenv): env = config.get("environment") if not env: - if "GL_USER" in osenv and "GL_REPO" in osenv: - env = "gitolite" - else: - env = "generic" + env = "generic" return env @@ -4139,7 +4071,6 @@ def build_environment_klass(env_name): GerritEnvironment = build_environment_klass("gerrit") StashEnvironment = build_environment_klass("stash") -GitoliteEnvironment = build_environment_klass("gitolite") GenericEnvironment = build_environment_klass("generic") diff --git a/pagure/hooks/mail.py b/pagure/hooks/mail.py index f7c503f..44f5e31 100644 --- a/pagure/hooks/mail.py +++ b/pagure/hooks/mail.py @@ -88,9 +88,6 @@ class MailRunner(BaseRunner): "multimailhook.mailingList", "", project.mail_hook.mail_to ) repo_obj.config.set_multivar( - "multimailhook.environment", "", "gitolite" - ) - repo_obj.config.set_multivar( "multimailhook.repoName", "", project.fullname ) repo_obj.config.set_multivar("multimailhook.mailer", "", "smtp") diff --git a/pagure/lib/git.py b/pagure/lib/git.py index 9c2d710..025b83d 100644 --- a/pagure/lib/git.py +++ b/pagure/lib/git.py @@ -143,36 +143,6 @@ Subject: {subject} return "".join(filter(None, patch)) -def generate_gitolite_acls(project=None, group=None): - """Generate the gitolite configuration file. - - :arg project: the project of which to update the ACLs. This argument - can take three values: ``-1``, ``None`` and a project. - If project is ``-1``, the configuration should be refreshed for - *all* projects. - If project is ``None``, there no specific project to refresh - but the ssh key of an user was added and updated. - If project is a pagure.lib.model.Project, the configuration of - this project should be updated. - :type project: None, int or pagure.lib.model.Project - :kwarg group: the group to refresh the members of - :type group: None or str - - """ - if project != -1: - task = pagure.lib.tasks.generate_gitolite_acls.delay( - namespace=project.namespace if project else None, - name=project.name if project else None, - user=project.user.user if project and project.is_fork else None, - group=group, - ) - else: - task = pagure.lib.tasks.generate_gitolite_acls.delay( - name=-1, group=group - ) - return task - - def update_git(obj, repo): """Schedules an update_repo task after determining arguments.""" ticketuid = None @@ -401,7 +371,6 @@ def get_user_from_json(session, jsondata, key="user"): fullname=fullname or username, default_email=default_email, emails=useremails, - keydir=pagure_config.get("GITOLITE_KEYDIR", None), ) session.commit() @@ -1119,9 +1088,6 @@ class TemporaryClone(object): ) env = os.environ.copy() env["GL_USER"] = username - env["GL_BYPASS_ACCESS_CHECKS"] = "1" - if pagure_config.get("GITOLITE_HOME"): - env["HOME"] = pagure_config["GITOLITE_HOME"] env.update(environ) env.update(extra) out = subprocess.check_output( @@ -2942,10 +2908,7 @@ def mirror_pull_project(session, project, debug=False): _log.debug("Running a git push to %s", project.fullname) env = os.environ.copy() env["GL_USER"] = "pagure" - env["GL_BYPASS_ACCESS_CHECKS"] = "1" env["internal"] = "yes" - if pagure_config.get("GITOLITE_HOME"): - env["HOME"] = pagure_config["GITOLITE_HOME"] env.update(environ) env.update(extra) out = subprocess.check_output( diff --git a/pagure/lib/git_auth.py b/pagure/lib/git_auth.py index 36f7c7a..97654bd 100644 --- a/pagure/lib/git_auth.py +++ b/pagure/lib/git_auth.py @@ -13,20 +13,12 @@ import abc import json import logging import os -import subprocess -import tempfile from io import open import pkg_resources -import werkzeug.utils from six import with_metaclass -from six.moves import dbm_gnu -import pagure.exceptions -import pagure.lib.model_base -import pagure.lib.query from pagure.config import config as pagure_config -from pagure.lib import model from pagure.utils import is_repo_collaborator, lookup_deploykey # logging.config.dictConfig(pagure_config.get('LOGGING') or {'version': 1}) @@ -42,7 +34,7 @@ def get_git_auth_helper(backend=None): :arg backend: The name of the backend to find on the system (declared via the entry_points in setup.py). Pagure comes by default with the following backends: - test_auth, gitolite2, gitolite3 + test_auth, pagure_authorized_keys :type backend: str """ @@ -70,8 +62,6 @@ def get_git_auth_helper(backend=None): _log.debug("Was unable to find any helpers, registering built-in") cls = { "test_auth": GitAuthTestHelper, - "gitolite2": Gitolite2Auth, - "gitolite3": Gitolite3Auth, "pagure": PagureGitAuth, "pagure_authorized_keys": PagureGitAuth, }[backend] @@ -92,48 +82,6 @@ class GitAuthHelper(with_metaclass(abc.ABCMeta, object)): is_dynamic = False @classmethod - @abc.abstractmethod - def generate_acls(self, project, group=None): - """This is the method that is called by pagure to generate the - configuration file. - - :arg project: the project of which to update the ACLs. This argument - can take three values: ``-1``, ``None`` and a project. - If project is ``-1``, the configuration should be refreshed for - *all* projects. - If project is ``None``, there no specific project to refresh - but the ssh key of an user was added and updated or a group - was removed. - If project is a pagure.lib.model.Project, the configuration of - this project should be updated. - :type project: None, int or pagure.lib.model.Project - :kwarg group: the group to refresh the members of - :type group: None or pagure.lib.model.PagureGroup - - (This behaviour is based on the workflow of gitolite, if you are - implementing a different auth backend and need more granularity, - feel free to let us know.) - - """ - pass - - @classmethod - @abc.abstractmethod - def remove_acls(self, session, project): - """This is the method that is called by pagure to remove a project - from the configuration file. - - :arg cls: the current class - :type: GitAuthHelper - :arg session: the session with which to connect to the database - :arg project: the project to remove from the gitolite configuration - file. - :type project: pagure.lib.model.Project - - """ - pass - - @classmethod # This method can't be marked as abstract, since it's new and that would # break backwards compatibility def check_acl(cls, session, project, username, refname, **info): @@ -191,680 +139,11 @@ def _read_file(filename): return stream.read() -class Gitolite2Auth(GitAuthHelper): - """A gitolite 2 authentication module.""" - - @classmethod - def _process_project(cls, project, config, global_pr_only): - """Generate the gitolite configuration for the specified project. - - :arg project: the project to generate the configuration for - :type project: pagure.lib.model.Project - :arg config: a list containing the different lines of the - configuration file - :type config: list - :arg groups: a dictionary containing the group name as key and the - users member of the group as values - :type groups: dict(str: list) - :arg global_pr_only: boolean on whether the pagure instance enforces - the PR workflow only or not - :type global_pr_only: bool - :return: the updated config - :return type: list - - """ - _log.debug(" Processing project: %s", project.fullname) - - # Check if the project or the pagure instance enforce the PR only - # development model. - pr_only = project.settings.get("pull_request_access_only", False) - - repos_to_create = ["repos"] - if pagure_config.get("ENABLE_DOCS", True): - repos_to_create.append("docs/") - if pagure_config.get("ENABLE_TICKETS", True): - repos_to_create.append("tickets/") - # no setting yet to disable pull-requests - repos_to_create.append("requests/") - for repos in repos_to_create: - if repos == "repos": - # Do not grant access to project enforcing the PR model - if pr_only or (global_pr_only and not project.is_fork): - continue - repos = "" - - config.append("repo %s%s" % (repos, project.fullname)) - if not project.private and repos not in ["tickets/", "requests/"]: - config.append(" R = @all") - if project.committer_groups: - config.append( - " RW+ = @%s" - % " @".join( - [ - group.group_name - for group in project.committer_groups - ] - ) - ) - config.append(" RW+ = %s" % project.user.user) - for user in project.committers: - # This should never be the case (that the project.user - # is in the committers) but better safe than sorry - if user.user != project.user.user: - config.append(" RW+ = %s" % user.user) - for deploykey in project.deploykeys: - access = "R" - if deploykey.pushaccess: - access = "RW+" - # Note: the replace of / with _ is because gitolite - # users can't contain a /. At first, this might look - # like deploy keys in a project called - # $namespace_$project would give access to the repos of - # a project $namespace/$project or vica versa, however - # this is NOT the case because we add the deploykey.id - # to the end of the deploykey name, which means it is - # unique. The project name is solely there to make it - # easier to determine what project created the deploykey - # for admins. - config.append( - " %s = deploykey_%s_%s" - % ( - access, - werkzeug.utils.secure_filename(project.fullname), - deploykey.id, - ) - ) - config.append("") - - return config - - @classmethod - def _clean_current_config(cls, current_config, project): - """Remove the specified project from the current configuration file - - :arg current_config: the content of the current/actual gitolite - configuration file read from the disk - :type current_config: list - :arg project: the project to update in the configuration file - :type project: pagure.lib.model.Project - - """ - keys = [ - "repo %s%s" % (repos, project.fullname) - for repos in ["", "docs/", "tickets/", "requests/"] - ] - - keep = True - config = [] - for line in current_config: - line = line.rstrip() - - if line in keys: - keep = False - continue - - if keep is False and line == "": - keep = True - - if keep: - config.append(line) - - return config - - @classmethod - def _clean_groups(cls, config, group=None): - """Removes the groups in the given configuration file. - - :arg config: the current configuration - :type config: list - :kwarg group: the group to refresh the members of - :type group: None or pagure.lib.model.PagureGroup - :return: the configuration without the groups - :return type: list - - """ - - if group is None: - output = [ - row.rstrip() - for row in config - if not row.startswith("@") and row.strip() != "# end of groups" - ] - else: - end_grp = None - seen = False - output = [] - for idx, row in enumerate(config): - if end_grp is None and row.startswith("repo "): - end_grp = idx - - if row.startswith("@%s " % group.group_name): - seen = True - row = "@%s = %s" % ( - group.group_name, - " ".join( - sorted([user.username for user in group.users]) - ), - ) - output.append(row) - - if not seen: - row = "@%s = %s" % ( - group.group_name, - " ".join(sorted([user.username for user in group.users])), - ) - output.insert(end_grp, "") - output.insert(end_grp, row) - - return output - - @classmethod - def _generate_groups_config(cls, session): - """Generate the gitolite configuration for all of the groups. - - :arg session: the session with which to connect to the database - :return: the gitolite configuration for the groups - :return type: list - - """ - query = session.query(model.PagureGroup).order_by( - model.PagureGroup.group_name - ) - - groups = {} - for grp in query.all(): - groups[grp.group_name] = [user.username for user in grp.users] - - return groups - - @classmethod - def _get_current_config(cls, configfile, preconfig=None, postconfig=None): - """Load the current gitolite configuration file from the disk. - - :arg configfile: the name of the configuration file to load - :type configfile: str - :kwarg preconf: the content of the file to include at the top of the - gitolite configuration file, used here to determine that a part of - the configuration file should be cleaned at the top. - :type preconf: None or str - :kwarg postconf: the content of the file to include at the bottom of - the gitolite configuration file, used here to determine that a part - of the configuration file should be cleaned at the bottom. - :type postconf: None or str - - """ - _log.info("Reading in the current configuration: %s", configfile) - with open(configfile) as stream: - current_config = [line.rstrip() for line in stream] - if current_config and current_config[-1] == "# end of body": - current_config = current_config[:-1] - - if preconfig: - idx = None - for idx, row in enumerate(current_config): - if row.strip() == "# end of header": - break - if idx is not None: - idx = idx + 1 - _log.info("Removing the first %s lines", idx) - current_config = current_config[idx:] - - if postconfig: - idx = None - for idx, row in enumerate(current_config): - if row.strip() == "# end of body": - break - if idx is not None: - _log.info( - "Keeping the first %s lines out of %s", - idx, - len(current_config), - ) - current_config = current_config[:idx] - - return current_config - - @classmethod - def write_gitolite_acls( - cls, - session, - configfile, - project, - preconf=None, - postconf=None, - group=None, - ): - """Generate the configuration file for gitolite for all projects - on the forge. - - :arg cls: the current class - :type: Gitolite2Auth - :arg session: a session to connect to the database with - :arg configfile: the name of the configuration file to generate/write - :type configfile: str - :arg project: the project to update in the gitolite configuration - file. It can be of three types/values. - If it is ``-1`` or if the file does not exist on disk, the - entire gitolite configuration will be re-generated. - If it is ``None``, the gitolite configuration will have its - groups information updated but not the projects and will be - re-compiled. - If it is a ``pagure.lib.model.Project``, the gitolite - configuration will be updated for just this project. - :type project: None, int or spagure.lib.model.Project - :kwarg preconf: a file to include at the top of the configuration - file - :type preconf: None or str - :kwarg postconf: a file to include at the bottom of the - configuration file - :type postconf: None or str - :kwarg group: the group to refresh the members of - :type group: None or pagure.lib.model.PagureGroup - - """ - _log.info("Write down the gitolite configuration file") - - preconfig = None - if preconf: - _log.info( - "Loading the file to include at the top of the generated one" - ) - preconfig = _read_file(preconf) - - postconfig = None - if postconf: - _log.info( - "Loading the file to include at the end of the generated one" - ) - postconfig = _read_file(postconf) - - global_pr_only = pagure_config.get("PR_ONLY", False) - config = [] - groups = {} - if group is None: - groups = cls._generate_groups_config(session) - - if project == -1 or not os.path.exists(configfile): - _log.info("Refreshing the configuration for all projects") - query = session.query(model.Project).order_by(model.Project.id) - for project in query.all(): - config = cls._process_project(project, config, global_pr_only) - elif project: - _log.info("Refreshing the configuration for one project") - config = cls._process_project(project, config, global_pr_only) - - current_config = cls._get_current_config( - configfile, preconfig, postconfig - ) - - current_config = cls._clean_current_config(current_config, project) - - config = current_config + config - - if config: - _log.info("Cleaning the group %s from the loaded config", group) - config = cls._clean_groups(config, group=group) - - else: - current_config = cls._get_current_config( - configfile, preconfig, postconfig - ) - - _log.info("Cleaning the group %s from the config on disk", group) - config = cls._clean_groups(current_config, group=group) - - if not config: - return - - _log.info("Writing the configuration to: %s", configfile) - with open(configfile, "w", encoding="utf-8") as stream: - if preconfig: - stream.write(preconfig + "\n") - stream.write("# end of header\n") - - if groups: - for key in sorted(groups): - stream.write("@%s = %s\n" % (key, " ".join(groups[key]))) - stream.write("# end of groups\n\n") - - prev = None - for row in config: - if prev is None: - prev = row - if prev == row == "": - continue - stream.write(row + "\n") - prev = row - - stream.write("# end of body\n") - - if postconfig: - stream.write(postconfig + "\n") - - @classmethod - def _remove_from_gitolite_cache(cls, cache_file, project): - """Removes project from gitolite cache file (gl-conf.cache) - - Gitolite has no notion of "deleting" a project and it can only - add values to gl-conf.cache. Therefore we must manually wipe all - entries related to a project when deleting it. - If this method is not executed and if someone creates a project - with the same fullname again then its `gl-conf` file won't get - created (see link to commit below) and any subsequent invocation of - `gitolite trigger POST_COMPILE` will fail, thus preventing creation - of new repos/forks at the whole pagure instance. - - See https://github.com/sitaramc/gitolite/commit/41b7885b77c - (later reverted upstream, but still used in most Pagure deployments) - - :arg cls: the current class - :type: Gitolite2Auth - :arg cache_file: path to the cache file - :type cache_file: str - :arg project: the project to remove from gitolite cache file - :type project: pagure.lib.model.Project - """ - _log.info("Remove project from the gitolite cache file") - cf = None - try: - # unfortunately dbm_gnu.open isn't a context manager in Python 2 :( - cf = dbm_gnu.open(cache_file, "ws") - for repo in ["", "docs/", "tickets/", "requests/"]: - to_remove = repo + project.fullname - if to_remove.encode("ascii") in cf: - del cf[to_remove] - except dbm_gnu.error as e: - msg = "Failed to remove project from gitolite cache: {msg}".format( - msg=e[1] - ) - raise pagure.exceptions.PagureException(msg) - finally: - if cf: - cf.close() - - @classmethod - def remove_acls(cls, session, project): - """Remove a project from the configuration file for gitolite. - - :arg cls: the current class - :type: Gitolite2Auth - :arg session: the session with which to connect to the database - :arg project: the project to remove from the gitolite configuration - file. - :type project: pagure.lib.model.Project - - """ - _log.info("Remove project from the gitolite configuration file") - - if not project: - raise RuntimeError("Project undefined") - - configfile = pagure_config["GITOLITE_CONFIG"] - preconf = pagure_config.get("GITOLITE_PRE_CONFIG") or None - postconf = pagure_config.get("GITOLITE_POST_CONFIG") or None - - if not os.path.exists(configfile): - _log.info( - "Not configuration file found at: %s... bailing" % configfile - ) - return - - preconfig = None - if preconf: - _log.info( - "Loading the file to include at the top of the generated one" - ) - preconfig = _read_file(preconf) - - postconfig = None - if postconf: - _log.info( - "Loading the file to include at the end of the generated one" - ) - postconfig = _read_file(postconf) - - config = [] - groups = cls._generate_groups_config(session) - - _log.info("Removing the project from the configuration") - - current_config = cls._get_current_config( - configfile, preconfig, postconfig - ) - - current_config = cls._clean_current_config(current_config, project) - - config = current_config + config - - if config: - _log.info("Cleaning the groups from the loaded config") - config = cls._clean_groups(config) - - else: - current_config = cls._get_current_config( - configfile, preconfig, postconfig - ) - - _log.info("Cleaning the groups from the config on disk") - config = cls._clean_groups(config) - - if not config: - return - - _log.info("Writing the configuration to: %s", configfile) - with open(configfile, "w", encoding="utf-8") as stream: - if preconfig: - stream.write(preconfig + "\n") - stream.write("# end of header\n") - - if groups: - for key in sorted(groups): - stream.write("@%s = %s\n" % (key, " ".join(groups[key]))) - stream.write("# end of groups\n\n") - - prev = None - for row in config: - if prev is None: - prev = row - if prev == row == "": - continue - stream.write(row + "\n") - prev = row - - stream.write("# end of body\n") - - if postconfig: - stream.write(postconfig + "\n") - - gl_cache_path = os.path.join( - os.path.dirname(configfile), "..", "gl-conf.cache" - ) - if os.path.exists(gl_cache_path): - cls._remove_from_gitolite_cache(gl_cache_path, project) - - @staticmethod - def _get_gitolite_command(): - """Return the gitolite command to run based on the info in the - configuration file. - """ - _log.info("Compiling the gitolite configuration") - gitolite_folder = pagure_config.get("GITOLITE_HOME", None) - if gitolite_folder: - cmd = "GL_RC=%s GL_BINDIR=%s gl-compile-conf" % ( - pagure_config.get("GL_RC"), - pagure_config.get("GL_BINDIR"), - ) - _log.debug("Command: %s", cmd) - return cmd - - @classmethod - def _repos_from_lines(cls, lines): - """Return list of strings representing complete repo entries from list - of lines as returned by _process_project. - """ - repos = [] - for line in lines: - if line.startswith("repo "): - repos.append([line]) - else: - repos[-1].append(line) - for i, repo_lines in enumerate(repos): - repos[i] = "\n".join(repo_lines) - return repos - - @classmethod - def _run_gitolite_cmd(cls, cmd): - """Run gitolite command as subprocess, raise PagureException - if it fails. - """ - if cmd: - proc = subprocess.Popen( - cmd, - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - cwd=pagure_config["GITOLITE_HOME"], - ) - stdout, stderr = proc.communicate() - if proc.returncode != 0: - error_msg = ( - 'The command "{0}" failed with' - '\n\n out: "{1}\n\n err:"{2}"'.format( - cmd, stdout, stderr - ) - ) - raise pagure.exceptions.PagureException(error_msg) - - @classmethod - def generate_acls(cls, project, group=None): - """Generate the gitolite configuration file for all repos - - :arg project: the project to update in the gitolite configuration - file. It can be of three types/values. - If it is ``-1`` or if the file does not exist on disk, the - entire gitolite configuration will be re-generated. - If it is ``None``, the gitolite configuration will not be - changed but will be re-compiled. - If it is a ``pagure.lib.model.Project``, the gitolite - configuration will be updated for just this project. - :type project: None, int or pagure.lib.model.Project - :kwarg group: the group to refresh the members of - :type group: None or pagure.lib.model.PagureGroup - - """ - _log.info("Refresh gitolite configuration") - - if project is not None or group is not None: - session = pagure.lib.model_base.create_session( - pagure_config["DB_URL"] - ) - cls.write_gitolite_acls( - session, - project=project, - configfile=pagure_config["GITOLITE_CONFIG"], - preconf=pagure_config.get("GITOLITE_PRE_CONFIG") or None, - postconf=pagure_config.get("GITOLITE_POST_CONFIG") or None, - group=group, - ) - session.remove() - - if ( - not group - and project not in [None, -1] - and hasattr(cls, "_individual_repos_command") - and pagure_config.get("GITOLITE_HAS_COMPILE_1", False) - ): - # optimization for adding single repo - we don't want to recompile - # whole gitolite.conf - repos_config = [] - cls._process_project( - project, repos_config, pagure_config.get("PR_ONLY", False) - ) - # repos_config will contain lines for repo itself as well as - # docs, requests, tickets; compile-1 only accepts one repo, - # so we have to run it separately for all of them - for repo in cls._repos_from_lines(repos_config): - repopath = repo.splitlines()[0][len("repo ") :].strip() - repotype = repopath.split("/")[0] - if ( - repotype == "docs" and not pagure_config.get("ENABLE_DOCS") - ) or ( - repotype == "tickets" - and not pagure_config.get("ENABLE_TICKETS") - ): - continue - with tempfile.NamedTemporaryFile() as f: - f.write(repo) - f.flush() - cmd = cls._individual_repos_command(f.name) - cls._run_gitolite_cmd(cmd) - else: - cmd = cls._get_gitolite_command() - cls._run_gitolite_cmd(cmd) - - -class Gitolite3Auth(Gitolite2Auth): - """A gitolite 3 authentication module.""" - - @staticmethod - def _individual_repos_command(config_file): - _log.info( - "Compiling gitolite configuration %s for single repository", - config_file, - ) - gitolite_folder = pagure_config.get("GITOLITE_HOME", None) - if gitolite_folder: - cmd = "HOME=%s gitolite compile-1 %s" % ( - gitolite_folder, - config_file, - ) - _log.debug("Command: %s", cmd) - return cmd - - @staticmethod - def _get_gitolite_command(): - """Return the gitolite command to run based on the info in the - configuration file. - """ - _log.info("Compiling the gitolite configuration") - gitolite_folder = pagure_config.get("GITOLITE_HOME", None) - if gitolite_folder: - cmd = ( - "HOME=%s gitolite compile && HOME=%s gitolite trigger " - "POST_COMPILE" % (gitolite_folder, gitolite_folder) - ) - _log.debug("Command: %s", cmd) - return cmd - - @classmethod - def post_compile_only(cls): - """This method runs `gitolite trigger POST_COMPILE` without touching - any other gitolite configuration. Most importantly, this will process - SSH keys used by gitolite. - """ - _log.info("Triggering gitolite POST_COMPILE") - gitolite_folder = pagure_config.get("GITOLITE_HOME", None) - if gitolite_folder: - cmd = "HOME=%s gitolite trigger POST_COMPILE" % gitolite_folder - _log.debug("Command: %s", cmd) - cls._run_gitolite_cmd(cmd) - - class PagureGitAuth(GitAuthHelper): """Standard Pagure git auth implementation.""" is_dynamic = True - @classmethod - def generate_acls(self, project, group=None): - """This function is required but not used.""" - pass - - @classmethod - def remove_acls(self, session, project): - """This function is required but not used.""" - pass - def info(self, msg): """Function that prints info about decisions to clients. @@ -918,45 +197,6 @@ class GitAuthTestHelper(GitAuthHelper): is_dynamic = True @classmethod - def generate_acls(cls, project, group=None): - """Print a statement when called, useful for debugging, only. - - :arg project: this variable is just printed out but not used - in any real place. - :type project: None, int or spagure.lib.model.Project - :kwarg group: the group to refresh the members of - :type group: None or pagure.lib.model.PagureGroup - - """ - out = ( - "Called GitAuthTestHelper.generate_acls() " - "with args: project=%s, group=%s" % (project, group) - ) - print(out) - return out - - @classmethod - def remove_acls(cls, session, project): - """Print a statement about which a project would be removed from - the configuration file for gitolite. - - :arg cls: the current class - :type: GitAuthHelper - :arg session: the session with which to connect to the database - :arg project: the project to remove from the gitolite configuration - file. - :type project: pagure.lib.model.Project - - """ - - out = ( - "Called GitAuthTestHelper.remove_acls() " - "with args: project=%s" % (project.fullname) - ) - print(out) - return out - - @classmethod def check_acl( cls, session, project, username, refname, pull_request, **info ): diff --git a/pagure/lib/model.py b/pagure/lib/model.py index 4c63aef..3e595d3 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -383,7 +383,6 @@ class Project(BASE): hook_token = sa.Column(sa.String(40), nullable=False, unique=True) avatar_email = sa.Column(sa.Text, nullable=True) is_fork = sa.Column(sa.Boolean, default=False, nullable=False) - read_only = sa.Column(sa.Boolean, default=True, nullable=False) parent_id = sa.Column( sa.Integer, sa.ForeignKey("projects.id", onupdate="CASCADE"), diff --git a/pagure/lib/notify.py b/pagure/lib/notify.py index 53b1eaa..6d5d23c 100644 --- a/pagure/lib/notify.py +++ b/pagure/lib/notify.py @@ -1104,7 +1104,7 @@ def notify_new_commits(abspath, project, branch, commits): been added. """ # string note: abspath, project and branch can only contain ASCII - # by policy (pagure and/or gitolite) + # by policy (pagure) commits_info = [] for commit in commits: commits_info.append( diff --git a/pagure/lib/query.py b/pagure/lib/query.py index a206daf..839d2ae 100644 --- a/pagure/lib/query.py +++ b/pagure/lib/query.py @@ -283,93 +283,6 @@ def find_ssh_key(session, search_key, username): return None -def create_deploykeys_ssh_keys_on_disk(project, gitolite_keydir): - """Create the ssh keys for the projects' deploy keys on the key dir. - - This method does NOT support multiple ssh keys per deploy key. - """ - if not gitolite_keydir: - # Nothing to do here, move right along - return - - # First remove deploykeys that no longer exist - keyfiles = [ - "deploykey_%s_%s.pub" - % (werkzeug.utils.secure_filename(project.fullname), key.id) - for key in project.deploykeys - ] - - project_key_dir = os.path.join( - gitolite_keydir, "deploykeys", project.fullname - ) - if not os.path.exists(project_key_dir): - os.makedirs(project_key_dir) - - for keyfile in os.listdir(project_key_dir): - if keyfile not in keyfiles: - # This key is no longer in the project. Remove it. - os.remove(os.path.join(project_key_dir, keyfile)) - - for deploykey in project.deploykeys: - # See the comment in lib/git.py:write_gitolite_acls about why this - # name for a file is sane and does not inject a new security risk. - keyfile = "deploykey_%s_%s.pub" % ( - werkzeug.utils.secure_filename(project.fullname), - deploykey.id, - ) - if not os.path.exists(os.path.join(project_key_dir, keyfile)): - # We only take the very first key - deploykeys must be single keys - key = deploykey.public_ssh_key.split("\n")[0] - if not key: - continue - if not is_valid_ssh_key(key): - continue - with open(os.path.join(project_key_dir, keyfile), "w") as f: - f.write(deploykey.public_ssh_key) - - -def create_user_ssh_keys_on_disk(user, gitolite_keydir): - """Create the ssh keys for the user on the specific folder. - - This is the method allowing to have multiple ssh keys per user. - """ - if gitolite_keydir: - # First remove any old keyfiles for the user - # Assumption: we populated the keydir. This means that files - # will be in 0/.pub, ..., and not in any deeper - # directory structures. Also, this means that if a user - # had 5 lines, they will be up to at most keys_4/.pub, - # meaning that if a user is not in keys_/.pub, with - # i being any integer, the user is most certainly not in - # keys_/.pub. - i = 0 - keyline_file = os.path.join( - gitolite_keydir, "keys_%i" % i, "%s.pub" % user.user - ) - while os.path.exists(keyline_file): - os.unlink(keyline_file) - i += 1 - keyline_file = os.path.join( - gitolite_keydir, "keys_%i" % i, "%s.pub" % user.user - ) - - if not user.sshkeys: - return - - # Now let's create new keyfiles for the user - i = 0 - for key in user.sshkeys: - if not is_valid_ssh_key(key.public_ssh_key): - continue - keyline_dir = os.path.join(gitolite_keydir, "keys_%i" % i) - if not os.path.exists(keyline_dir): - os.mkdir(keyline_dir) - keyfile = os.path.join(keyline_dir, "%s.pub" % user.user) - with open(keyfile, "w") as stream: - stream.write(key.public_ssh_key.strip()) - i += 1 - - def add_issue_comment( session, issue, @@ -1182,7 +1095,6 @@ def add_user_to_project( access_obj.access = access access_obj.branches = branches project.date_modified = datetime.datetime.utcnow() - update_read_only_mode(session, project, read_only=True) session.add(access_obj) session.add(project) session.commit() @@ -1209,8 +1121,6 @@ def add_user_to_project( ) project.date_modified = datetime.datetime.utcnow() session.add(project_user) - # Mark the project as read only, celery will then unmark it - update_read_only_mode(session, project, read_only=True) session.add(project) # Commit so the JSON sent in the notification is up to date session.commit() @@ -1295,7 +1205,6 @@ def add_group_to_project( access_obj.branches = branches session.add(access_obj) project.date_modified = datetime.datetime.utcnow() - update_read_only_mode(session, project, read_only=True) session.add(project) # Commit so the JSON sent in the notification is up to date session.commit() @@ -1323,8 +1232,6 @@ def add_group_to_project( session.add(project_group) # Make sure we won't have SQLAlchemy error before we continue project.date_modified = datetime.datetime.utcnow() - # Mark the project read_only, celery will then unmark it - update_read_only_mode(session, project, read_only=True) session.add(project) # Commit so the JSON sent in the notification is up to date session.commit() @@ -2289,10 +2196,8 @@ def update_project_settings(session, repo, settings, user, from_api=False): ) if "pull_request_access_only" in update: - update_read_only_mode(session, repo, read_only=True) session.add(repo) session.flush() - pagure.lib.git.generate_gitolite_acls(project=repo) return "Edited successfully settings of repo: %s" % repo.fullname @@ -3680,13 +3585,7 @@ def get_commit_flag_by_uid(session, commit_hash, flag_uid): def set_up_user( - session, - username, - fullname, - default_email, - emails=None, - ssh_key=None, - keydir=None, + session, username, fullname, default_email, emails=None, ssh_key=None ): """Set up a new user into the database or update its information.""" user = search_user(session, username=username) @@ -3714,7 +3613,7 @@ def set_up_user( _log.exception(err) if ssh_key and not user.sshkeys: - update_user_ssh(session, user, ssh_key, keydir) + update_user_ssh(session, user, ssh_key) return user @@ -3751,7 +3650,7 @@ def add_email_to_user(session, user, user_email): update_log_email_user(session, user_email, user) -def update_user_ssh(session, user, ssh_key, keydir, update_only=False): +def update_user_ssh(session, user, ssh_key): """Set up a new user into the database or update its information.""" if isinstance(user, six.string_types): user = get_user(session, user) @@ -3770,12 +3669,6 @@ def update_user_ssh(session, user, ssh_key, keydir, update_only=False): ) session.commit() - if keydir: - create_user_ssh_keys_on_disk(user, keydir) - if update_only: - pagure.lib.tasks.gitolite_post_compile_only.delay() - else: - pagure.lib.git.generate_gitolite_acls(project=None) session.add(user) session.flush() @@ -5653,30 +5546,6 @@ def has_starred(session, repo, user): return False -def update_read_only_mode(session, repo, read_only=True): - """Remove the read only mode from the project - - :arg session: The session object to query the db with - :arg repo: model.Project object to mark/unmark read only - :arg read_only: True if project is to be made read only, - False otherwise - """ - - if ( - not repo - or not isinstance(repo, model.Project) - or read_only not in [True, False] - ): - return - helper = pagure.lib.git_auth.get_git_auth_helper() - if helper.is_dynamic and read_only: - # No need to set a readonly flag if a dynamic auth backend is in use - return - if repo.read_only != read_only: - repo.read_only = read_only - session.add(repo) - - def issues_history_stats(session, project, detailed=False, weeks_range=53): """Returns the number of opened issues on the specified project over the last 365 days @@ -5867,11 +5736,8 @@ def remove_user_of_project(session, user, project, agent): project.users.remove(u) break - # Mark the project as read_only, celery will unmark it - update_read_only_mode(session, project, read_only=True) session.commit() - pagure.lib.git.generate_gitolite_acls(project=project) pagure.lib.notify.log( project, topic="project.user.removed", diff --git a/pagure/lib/tasks.py b/pagure/lib/tasks.py index f4c50bd..87ceea4 100644 --- a/pagure/lib/tasks.py +++ b/pagure/lib/tasks.py @@ -84,82 +84,14 @@ def ret(endpoint, **kwargs): return toret -@conn.task(queue=pagure_config.get("GITOLITE_CELERY_QUEUE", None), bind=True) -@pagure_task -def generate_gitolite_acls( - self, session, namespace=None, name=None, user=None, group=None -): - """Generate the gitolite configuration file either entirely or for a - specific project. - - :arg session: SQLAlchemy session object - :type session: sqlalchemy.orm.session.Session - :kwarg namespace: the namespace of the project - :type namespace: None or str - :kwarg name: the name of the project - :type name: None or str - :kwarg user: the user of the project, only set if the project is a fork - :type user: None or str - :kwarg group: the group to refresh the members of - :type group: None or str - - """ - project = None - if name and name != -1: - project = pagure.lib.query._get_project( - session, namespace=namespace, name=name, user=user - ) - - elif name == -1: - project = name - helper = pagure.lib.git_auth.get_git_auth_helper() - _log.debug("Got helper: %s", helper) - - group_obj = None - if group: - group_obj = pagure.lib.query.search_groups(session, group_name=group) - _log.debug( - "Calling helper: %s with arg: project=%s, group=%s", - helper, - project, - group_obj, - ) - helper.generate_acls(project=project, group=group_obj) - - pagure.lib.query.update_read_only_mode(session, project, read_only=False) - try: - session.commit() - _log.debug("Project %s is no longer in Read Only Mode", project) - except SQLAlchemyError: - session.rollback() - _log.exception("Failed to unmark read_only for: %s project", project) - - -@conn.task(queue=pagure_config.get("GITOLITE_CELERY_QUEUE", None), bind=True) -@pagure_task -def gitolite_post_compile_only(self, session): - """Do gitolite post-processing only. Most importantly, this processes SSH - keys used by gitolite. This is an optimization task that's supposed to be - used if you only need to run `gitolite trigger POST_COMPILE` without - touching any other gitolite configuration - """ - helper = pagure.lib.git_auth.get_git_auth_helper() - _log.debug("Got helper: %s", helper) - if hasattr(helper, "post_compile_only"): - helper.post_compile_only() - else: - helper.generate_acls(project=None) - - -@conn.task(queue=pagure_config.get("GITOLITE_CELERY_QUEUE", None), bind=True) +@conn.task(queue=pagure_config.get("FAST_CELERY_QUEUE", None), bind=True) @pagure_task def delete_project( self, session, namespace=None, name=None, user=None, action_user=None ): """Delete a project in pagure. - This is achieved in three steps: - - Remove the project from gitolite.conf + This is achieved in two steps: - Remove the git repositories on disk - Remove the project from the DB @@ -185,14 +117,12 @@ def delete_project( % (namespace, name, user) ) - # Remove the project from gitolite.conf helper = pagure.lib.git_auth.get_git_auth_helper() _log.debug("Got helper: %s", helper) _log.debug( "Calling helper: %s with arg: project=%s", helper, project.fullname ) - helper.remove_acls(session=session, project=project) # Remove the git repositories on disk pagure.lib.git.delete_project_repos(project) @@ -323,13 +253,6 @@ def create_project( master_ref = temp_gitrepo.lookup_reference("HEAD").resolve() tempclone.push("pagure", master_ref.name, internal="yes") - task = generate_gitolite_acls.delay( - namespace=project.namespace, - name=project.name, - user=project.user.user if project.is_fork else None, - ) - _log.info("Refreshing gitolite config queued in task: %s", task.id) - return ret("ui_ns.view_repo", repo=name, namespace=namespace) @@ -527,13 +450,7 @@ def fork( msg=dict(project=repo_to.to_json(public=True), agent=user_forker), ) - _log.info("Project created, refreshing auth async") - task = generate_gitolite_acls.delay( - namespace=repo_to.namespace, - name=repo_to.name, - user=repo_to.user.user if repo_to.is_fork else None, - ) - _log.info("Refreshing gitolite config queued in task: %s", task.id) + _log.info("Project created.") if editfile is None: return ret( diff --git a/pagure/templates/repo_master.html b/pagure/templates/repo_master.html index 91b7830..990b902 100644 --- a/pagure/templates/repo_master.html +++ b/pagure/templates/repo_master.html @@ -8,9 +8,6 @@ {% elif not (current_user | user_group_can_ssh_commit) %} Only members of the {{ config["SSH_ACCESS_GROUPS"] | join(", ") }} group(s) can clone via ssh - {% elif repo.read_only %} - The permissions on this repository are being updated. - Cloning over SSH is disabled. {% else %}
@@ -260,19 +257,6 @@
- {% if repo.read_only %} -
- -
- {% endif %} {% if g.authenticated and repo.settings.get('pull_request_access_only') %}