diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 0000000..60eb53d --- /dev/null +++ b/.arcconfig @@ -0,0 +1,9 @@ +{ + "phabricator.uri": "https://we.phorge.it/", + "load": [ + "src/" + ], + "history.immutable": true, + "arc.land.onto": ["main"], + "arc.land.strategy": "squash" +} diff --git a/.arclint b/.arclint new file mode 100644 index 0000000..bcfb403 --- /dev/null +++ b/.arclint @@ -0,0 +1,69 @@ +{ + "exclude": [ + "(^externals/)" + ], + "linters": { + "chmod": { + "type": "chmod" + }, + "filename": { + "type": "filename" + }, + "generated": { + "type": "generated" + }, + "json": { + "type": "json", + "include": [ + "(^resources/arclint/.*\\.arclint\\.example$)", + "(^\\.arcconfig$)", + "(^\\.arclint$)", + "(\\.json$)" + ] + }, + "merge-conflict": { + "type": "merge-conflict" + }, + "nolint": { + "type": "nolint" + }, + "phutil-library": { + "type": "phutil-library", + "include": "(\\.php$)" + }, + "spelling": { + "type": "spelling", + "exclude": "(^resources/spelling/.*\\.json$)" + }, + "text": { + "type": "text", + "exclude": [ + "(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect)|/Makefile\\z)" + ] + }, + "text-without-length": { + "type": "text", + "include": [ + "(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect))" + ], + "severity": { + "3": "disabled" + } + }, + "text-without-tabs": { + "type": "text", + "include": [ + "(/Makefile\\z)" + ], + "severity": { + "2": "disabled" + } + }, + "xhpast": { + "type": "xhpast", + "include": "(\\.php$)", + "standard": "phutil.xhpast", + "xhpast.php-version": "5.5.0" + } + } +} diff --git a/.devcontainer/.env.sample b/.devcontainer/.env.sample new file mode 100644 index 0000000..b62da80 --- /dev/null +++ b/.devcontainer/.env.sample @@ -0,0 +1,12 @@ +#.env sample file for the phorge-devcontainer + +# The HTTP Port that Phorge will run on +PHORGE_WEB_PORT=80 + +# The SSH Port that Phorge Repos will run on +PHORGE_SSH_PORT=22280 + +# The base URI that you will map on your local machine to 127.0.0.1 +# NOTE: If you use a PHORGE_WEB_PORT other than port 80, you will need to update this URI to include the port +# For example, if PHORGE_WEB_PORT=8020 then set PHORGE_BASE_URI=http://phorge.localhost:8020 +PHORGE_BASE_URI=http://phorge.localhost diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.devcontainer/.gitignore @@ -0,0 +1 @@ +.env diff --git a/.devcontainer/.vscode/launch.json b/.devcontainer/.vscode/launch.json new file mode 100644 index 0000000..8166a78 --- /dev/null +++ b/.devcontainer/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9003 + }, + ] +} diff --git a/.devcontainer/application/Dockerfile b/.devcontainer/application/Dockerfile new file mode 100644 index 0000000..f9744d1 --- /dev/null +++ b/.devcontainer/application/Dockerfile @@ -0,0 +1,65 @@ +FROM debian:bookworm-backports + + +# == Get ca-certificates up to date == +RUN apt-get -y update +RUN apt-get -y install ca-certificates + + +# == Copy Data == +COPY install_scripts /install_scripts + +# == Configure Ubuntu == +WORKDIR /install_scripts +RUN sh install_dependencies.sh +RUN sh add_users.sh + +# == Set up the Phorge code base == +RUN mkdir /srv/phorge +RUN chown git:wwwgrp-phorge /srv/phorge +USER git +WORKDIR /srv/phorge +RUN git clone https://we.phorge.it/source/phorge.git +RUN git clone https://we.phorge.it/source/arcanist.git +USER root +WORKDIR / +RUN mkdir -p /var/tmp/phd/log +RUN chown phorge-daemon:2000 /var/tmp/phd/log + +# == Expose Ports == + +# Nginx +EXPOSE 80 +# Aphlict +EXPOSE 22280 +# SSH +EXPOSE 2222 + +# == Add service config files == +ADD /config/nginx.conf.org /etc/nginx/ +ADD /config/fastcgi.conf /etc/nginx/ +ADD /config/php-fpm.conf /etc/php/8.2/fpm/ +ADD /config/php.ini /etc/php/8.2/fpm/ +ADD /config/php.ini /etc/php/8.2/cli/ +ADD /config/aphlict.phorge.json /install_scripts/ + +# == Add Supervisord config files == +RUN mkdir -p /var/log/supervisor +RUN mkdir -p /etc/supervisor/conf.d/ + +ADD config/supervisord.conf /etc/supervisor/ +COPY config/*.sv.conf /etc/supervisor/conf.d/ + +# == Configure Phorge SSH service == +RUN mkdir /etc/phorge-ssh +RUN mkdir /var/run/sshd/ +RUN chmod 0755 /var/run/sshd +ADD config/sshd_config.phorge /etc/phorge-ssh/ +ADD config/phorge-ssh-hook.sh /etc/phorge-ssh/ +RUN chown root:root /etc/phorge-ssh/* + +# == Copy other scripts == # +COPY user-config /user-config +COPY startup.sh / + +CMD bash ./startup.sh && supervisord diff --git a/.devcontainer/application/config/aphlict.phorge.json b/.devcontainer/application/config/aphlict.phorge.json new file mode 100644 index 0000000..24bfe08 --- /dev/null +++ b/.devcontainer/application/config/aphlict.phorge.json @@ -0,0 +1,13 @@ +[{ + "type": "client", + "host": "phorge.localhost", + "port": 22280, + "protocol": "http" + }, + { + "type": "admin", + "host": "127.0.0.1", + "port": 22281, + "protocol": "http" + } +] diff --git a/.devcontainer/application/config/aphlict.sv.conf b/.devcontainer/application/config/aphlict.sv.conf new file mode 100644 index 0000000..a3005dc --- /dev/null +++ b/.devcontainer/application/config/aphlict.sv.conf @@ -0,0 +1,3 @@ +[program:aphlict] +command=/srv/phorge/phorge/bin/aphlict debug --config /srv/phorge/phorge/conf/aphlict/aphlict.default.json +user=phorge-daemon diff --git a/.devcontainer/application/config/fastcgi.conf b/.devcontainer/application/config/fastcgi.conf new file mode 100644 index 0000000..4419b42 --- /dev/null +++ b/.devcontainer/application/config/fastcgi.conf @@ -0,0 +1,24 @@ + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param DOCUMENT_URI $document_uri; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SERVER_PROTOCOL $server_protocol; + + fastcgi_param GATEWAY_INTERFACE CGI/1.1; + fastcgi_param SERVER_SOFTWARE nginx; + + fastcgi_param REMOTE_ADDR $remote_addr; + fastcgi_param REMOTE_PORT $remote_port; + fastcgi_param SERVER_ADDR $server_addr; + fastcgi_param SERVER_PORT $server_port; + fastcgi_param SERVER_NAME $server_name; + + fastcgi_param HTTPS $https; + + fastcgi_read_timeout 6000; diff --git a/.devcontainer/application/config/nginx.conf.org b/.devcontainer/application/config/nginx.conf.org new file mode 100644 index 0000000..bd81238 --- /dev/null +++ b/.devcontainer/application/config/nginx.conf.org @@ -0,0 +1,44 @@ +worker_processes 1; +daemon off; +pid /run/nginx.pid; + +events { + worker_connections 1024; + use epoll; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + gzip on; + client_max_body_size 200M; + client_body_buffer_size 200M; + + server { + listen *:80; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/access.log; + + root /srv/phorge/phorge/webroot; + try_files $uri $uri/ /index.php; + + location / { + index index.php; + + if ( !-f $request_filename ) + { + rewrite ^/(.*)$ /index.php?__path__=/$1 last; + break; + } + } + + location /index.php { + include /etc/nginx/fastcgi.conf; + fastcgi_param PATH "/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/bin:/usr/games"; + fastcgi_pass unix:/tmp/php-fpm-phorge.sock; + } + } +} diff --git a/.devcontainer/application/config/nginx.sv.conf b/.devcontainer/application/config/nginx.sv.conf new file mode 100644 index 0000000..dfa1572 --- /dev/null +++ b/.devcontainer/application/config/nginx.sv.conf @@ -0,0 +1,2 @@ +[program:nginx] +command=nginx diff --git a/.devcontainer/application/config/phorge-phd.sv.conf b/.devcontainer/application/config/phorge-phd.sv.conf new file mode 100644 index 0000000..836784e --- /dev/null +++ b/.devcontainer/application/config/phorge-phd.sv.conf @@ -0,0 +1,32 @@ +[program:PhabricatorRepositoryPullLocalDaemon] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorRepositoryPullLocalDaemon +stdout_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon.log +stderr_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon_err.log + +[program:PhabricatorTaskmasterDaemon1] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1_err.log + +[program:PhabricatorTaskmasterDaemon2] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2_err.log + +[program:PhabricatorTaskmasterDaemon3] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3_err.log + +[program:PhabricatorTaskmasterDaemon4] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4_err.log + +[group:phd] +programs=PhabricatorRepositoryPullLocalDaemon,PhabricatorTaskmasterDaemon1,PhabricatorTaskmasterDaemon2,PhabricatorTaskmasterDaemon3,PhabricatorTaskmasterDaemon4 diff --git a/.devcontainer/application/config/phorge-ssh-hook.sh b/.devcontainer/application/config/phorge-ssh-hook.sh new file mode 100644 index 0000000..4008bdf --- /dev/null +++ b/.devcontainer/application/config/phorge-ssh-hook.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# NOTE: Replace this with the username that you expect users to connect with. +VCSUSER="git" + +ROOT="/srv/phorge/phorge" + +if [ "$1" != "$VCSUSER" ]; +then + exit 1 +fi + +exec "$ROOT/bin/ssh-auth" $@ diff --git a/.devcontainer/application/config/phorge-sshd.sv.conf b/.devcontainer/application/config/phorge-sshd.sv.conf new file mode 100644 index 0000000..c7f5a8c --- /dev/null +++ b/.devcontainer/application/config/phorge-sshd.sv.conf @@ -0,0 +1,2 @@ +[program:phorge-sshd] +command=/usr/sbin/sshd -D -f /etc/phorge-ssh/sshd_config.phorge diff --git a/.devcontainer/application/config/php-fpm.conf b/.devcontainer/application/config/php-fpm.conf new file mode 100644 index 0000000..c202891 --- /dev/null +++ b/.devcontainer/application/config/php-fpm.conf @@ -0,0 +1,19 @@ +[global] +pid = /run/php-fpm.pid +error_log = /tmp/phorge.log +daemonize = no + +[phorge] +user = git +group = wwwgrp-phorge +listen = /tmp/php-fpm-phorge.sock +listen.owner = git +listen.group = wwwgrp-phorge +listen.mode = 0666 +pm = dynamic +pm.max_children = 4 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 4 +catch_workers_output = yes +php_admin_value[error_log] = /tmp/phorge.php.log diff --git a/.devcontainer/application/config/php.ini b/.devcontainer/application/config/php.ini new file mode 100644 index 0000000..340dfa7 --- /dev/null +++ b/.devcontainer/application/config/php.ini @@ -0,0 +1,190 @@ +[PHP] +engine = On +short_open_tag = Off +asp_tags = Off +precision = 14 +y2k_compliance = On +output_buffering = 4096 +zlib.output_compression = Off +unserialize_callback_func = +serialize_precision = 17 +allow_call_time_pass_reference = Off +safe_mode = Off +safe_mode_gid = Off +safe_mode_include_dir = +safe_mode_exec_dir = +safe_mode_allowed_env_vars = PHP_ +safe_mode_protected_env_vars = LD_LIBRARY_PATH +disable_functions = +disable_classes = +zend.enable_gc = On +expose_php = On +max_input_time = 60 +memory_limit = 4G +error_reporting = E_ALL & ~E_DEPRECATED +display_errors = On +display_startup_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +track_errors = Off +error_log = /tmp/php_errors.log +variables_order = "GPCS" +request_order = "GP" +register_globals = Off +register_long_arrays = Off +auto_globals_jit = On +post_max_size = 4G +magic_quotes_gpc = Off +magic_quotes_runtime = Off +magic_quotes_sybase = Off +auto_prepend_file = +auto_append_file = +default_mimetype = "text/html" +include_path = ".:/usr/share/php7:/usr/share/php7/PEAR:/srv/phorge/PHPExcel/Classes" +doc_root = +user_dir = +enable_dl = Off +file_uploads = On +upload_max_filesize = 4G +max_file_uploads = 20 +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 +opcache.validate_timestamps = On +opcache.revalidate_freq = 0 +xdebug.mode=debug +xdebug.start_with_request=true +[Date] +date.timezone = 'UTC' +[filter] +[iconv] +[intl] +[sqlite] +[sqlite3] +[Pcre] +[Pdo] +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket= +[Phar] +[Syslog] +define_syslog_variables = Off +[mail function] +SMTP = localhost +smtp_port = 25 +mail.add_x_header = On +[SQL] +sql.safe_mode = Off +[ODBC] +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 +[Interbase] +ibase.allow_persistent = 1 +ibase.max_persistent = -1 +ibase.max_links = -1 +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" +ibase.dateformat = "%Y-%m-%d" +ibase.timeformat = "%H:%M:%S" +[MySQL] +mysql.allow_local_infile = On +mysql.allow_persistent = Off +mysql.cache_size = 2000 +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 3 +mysql.trace_mode = Off +[MySQLi] +mysqli.max_persistent = -1 +mysqli.allow_persistent = Off +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off +[OCI8] +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 +[Sybase-CT] +sybct.allow_persistent = On +sybct.max_persistent = -1 +sybct.max_links = -1 +sybct.min_server_severity = 10 +sybct.min_client_severity = 10 +[bcmath] +bcmath.scale = 0 +[browscap] +[Session] +session.save_handler = files +session.save_path = "/var/lib/php5" +session.use_cookies = 1 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 +session.cookie_lifetime = 0 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = +session.serialize_handler = php +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.bug_compat_42 = Off +session.bug_compat_warn = Off +session.referer_check = +session.entropy_length = 32 +session.entropy_file = /dev/urandom +session.cache_limiter = nocache +session.cache_expire = 180 +session.use_trans_sid = 0 +session.hash_function = sha256 +session.hash_bits_per_character = 5 +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" +[MSSQL] +mssql.allow_persistent = On +mssql.max_persistent = -1 +mssql.max_links = -1 +mssql.min_error_severity = 10 +mssql.min_message_severity = 10 +mssql.compatability_mode = Off +mssql.secure_connection = Off +[Assertion] +[COM] +[mbstring] +[gd] +[exif] +[Tidy] +tidy.clean_output = Off +[soap] +soap.wsdl_cache_enabled=1 +soap.wsdl_cache_dir="/tmp" +soap.wsdl_cache_ttl=86400 +soap.wsdl_cache_limit = 5 +[sysvshm] +[ldap] +ldap.max_links = -1 +[mcrypt] +[dba] +[xsl] diff --git a/.devcontainer/application/config/php8-fpm.sv.conf b/.devcontainer/application/config/php8-fpm.sv.conf new file mode 100644 index 0000000..c46a972 --- /dev/null +++ b/.devcontainer/application/config/php8-fpm.sv.conf @@ -0,0 +1,2 @@ +[program:php-fpm8.2] +command=php-fpm8.2 -F diff --git a/.devcontainer/application/config/sshd_config.phorge b/.devcontainer/application/config/sshd_config.phorge new file mode 100644 index 0000000..6477458 --- /dev/null +++ b/.devcontainer/application/config/sshd_config.phorge @@ -0,0 +1,23 @@ +# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand +# was added in this version. + +# NOTE: Edit these to the correct values for your setup. + +AuthorizedKeysCommand /etc/phorge-ssh/phorge-ssh-hook.sh +AuthorizedKeysCommandUser git +AllowUsers git + +# You may need to tweak these options, but mostly they just turn off everything +# dangerous. + +Port 2222 +Protocol 2 +PermitRootLogin no +AllowAgentForwarding no +AllowTcpForwarding no +PrintMotd no +PrintLastLog no +PasswordAuthentication no +AuthorizedKeysFile none + +PidFile /run/sshd-phorge.pid diff --git a/.devcontainer/application/config/supervisord.conf b/.devcontainer/application/config/supervisord.conf new file mode 100644 index 0000000..180e8ec --- /dev/null +++ b/.devcontainer/application/config/supervisord.conf @@ -0,0 +1,29 @@ +; supervisor config file + +[unix_http_server] +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; sockef file mode (default 0700) + +[supervisord] +nodaemon=true +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket + +; The [include] section can just contain the "files" setting. This +; setting can list multiple files (separated by whitespace or +; newlines). It can also contain wildcards. The filenames are +; interpreted as relative to this file. Included files *cannot* +; include files themselves. + +[include] +files = /etc/supervisor/conf.d/*.conf diff --git a/.devcontainer/application/install_scripts/add_users.sh b/.devcontainer/application/install_scripts/add_users.sh new file mode 100644 index 0000000..cb92425 --- /dev/null +++ b/.devcontainer/application/install_scripts/add_users.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Add users +echo "git:x:2000:2000:user for phorge ssh:/srv/phorge:/bin/bash" >> /etc/passwd +echo "phorge-daemon:x:2001:2000:user for phorge daemons:/srv/phorge:/bin/bash" >> /etc/passwd +echo "wwwgrp-phorge:!:2000:nginx" >> /etc/group + +usermod -p NP git + +# Add repo directory +mkdir -p /var/repo/ +chown phorge-daemon:2000 /var/repo/ +mkdir -p /var/tmp/phd/pid +chmod 0777 /var/tmp/phd/pid + +# Add git to sudoers +echo "git ALL=(phorge-daemon) SETENV: NOPASSWD: /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/bin/git, /usr/lib/git-core/git-http-backend" > /etc/sudoers.d/git + +echo 'export PATH="/srv/phorge/arcanist/bin:$PATH"' >> /root/.bashrc +echo 'export PATH="/srv/phorge/phorge/bin:$PATH"' >> /root/.bashrc diff --git a/.devcontainer/application/install_scripts/install_dependencies.sh b/.devcontainer/application/install_scripts/install_dependencies.sh new file mode 100644 index 0000000..3808e39 --- /dev/null +++ b/.devcontainer/application/install_scripts/install_dependencies.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +export DEBIAN_FRONTEND=noninteractive + +apt-get -qq update +apt-get -y -qq install \ + git \ + nginx \ + php \ + php-fpm \ + php-mysql \ + php-gd \ + php-curl \ + php-apcu \ + php-cli \ + php-json \ + php-mbstring \ + php-zip \ + php-xdebug \ + ssh \ + wget \ + vim \ + less \ + zip \ + cron \ + lsof \ + sudo \ + supervisor \ + python3-pygments \ + mariadb-client \ + gcc \ + g++ \ + nodejs \ + npm diff --git a/.devcontainer/application/setup.php b/.devcontainer/application/setup.php new file mode 100644 index 0000000..09c4f61 --- /dev/null +++ b/.devcontainer/application/setup.php @@ -0,0 +1,68 @@ +#!/usr/bin/env php +setViewer(PhabricatorUser::getOmnipotentUser()) + ->withIDs(array(1)) + ->executeOne(); + +if ($config) { + echo phutil_console_wrap("User/Password Auth Provider already configured\n"); + return; +} + +echo phutil_console_wrap( + "Setting up dev environment with user admin/hunter2\n"); + +$password1 = new PhutilOpaqueEnvelope('hunter2'); + +$config = id(new PhabricatorAuthProviderConfig()) + ->setIsEnabled(1) + ->setShouldAllowLogin(1) + ->setShouldAllowRegistration(true) + ->setShouldAllowLink(1) + ->setShouldAllowUnlink(true) + ->setProviderType('password') + ->setProviderDomain('self') + ->setProviderClass('PhabricatorPasswordAuthProvider') + ->save(); + +$user = new PhabricatorUser(); +$user->setUsername('admin'); +$user->setRealName('admin'); + +$email = id(new PhabricatorUserEmail()) + ->setAddress('admin@example.com') + ->setIsVerified(1); + +$user->setIsApproved(1); + +id(new PhabricatorUserEditor()) + ->setActor(PhabricatorUser::getOmnipotentUser()) + ->createNewUser($user, $email); + +$xactions = array(); +$xactions[] = id(new PhabricatorUserTransaction()) + ->setTransactionType( + PhabricatorUserEmpowerTransaction::TRANSACTIONTYPE) + ->setNewValue(true); + +$source = id(new PhabricatorUnknownContentSource()); +$actor = PhabricatorUser::getOmnipotentUser(); +$people_application_phid = id(new PhabricatorPeopleApplication()) + ->getPHID(); + +$editor = id(new PhabricatorUserTransactionEditor()) + ->setActor($actor) + ->setContentSource($source) + ->setActingAsPHID($people_application_phid) + ->setContinueOnMissingFields(true); + +$editor->applyTransactions($user, $xactions); + +$pass = PhabricatorAuthPassword::initializeNewPassword($user, PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT) + ->setPassword($password1, $user) + ->save(); diff --git a/.devcontainer/application/startup.sh b/.devcontainer/application/startup.sh new file mode 100644 index 0000000..4e8d44f --- /dev/null +++ b/.devcontainer/application/startup.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +set -x + +echo "Waiting for mysql" +until mysql -h"$SQL_HOST" -P"$SQL_PORT" -u"$SQL_USER" -p"$SQL_PASSWORD" &> /dev/null +do + printf "." + sleep 1 +done + +echo -e "\nmysql ready" + +pushd /srv/phorge/phorge + +./bin/config set mysql.host $SQL_HOST +./bin/config set mysql.port $SQL_PORT +./bin/config set mysql.user $SQL_USER +./bin/config set mysql.pass $SQL_PASSWORD + +./bin/config set phabricator.base-uri $BASE_URI + +./bin/config set phd.user phorge-daemon +./bin/config set diffusion.ssh-user git +./bin/config set diffusion.ssh-port 2222 +./bin/config set diffusion.allow-http-auth true + +./bin/config set phabricator.developer-mode true +./bin/config set phabricator.show-prototypes true +./bin/config set darkconsole.enabled true + +./bin/config set storage.mysql-engine.max-size 268435456 +./bin/config set pygments.enabled true + +./bin/config set environment.append-paths '["/usr/lib/git-core"]' + +./bin/config set notification.servers --stdin < /install_scripts/aphlict.phorge.json + +echo '["/srv/phorge/gantt/src"]' | ./bin/config set load-libraries --stdin + +popd + +pushd /srv/phorge/phorge/support/aphlict/server + +npm ci + +popd + +cp /etc/nginx/nginx.conf.org /etc/nginx/nginx.conf + +pushd /srv/phorge/phorge + +./bin/storage upgrade --force + +php setup.php diff --git a/.devcontainer/application/user-config/.exists b/.devcontainer/application/user-config/.exists new file mode 100644 index 0000000..e69de29 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..b2f30db --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,26 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/docker-existing-docker-compose +{ + "name": "Deepclone Dev", + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "docker-compose.yml" + ], + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "app", + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/srv/phorge", + // Add the IDs of extensions you want installed when the container is created. + "customizations": { + "vscode": { + "extensions": [ + "bmewburn.vscode-intelephense-client", + "xdebug.php-debug", + "editorconfig.editorconfig" + ] + } + } +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..424a75b --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3.9" +services: + db: + image: mariadb + restart: always + volumes: + - ./mysql:/etc/mysql/conf.d:ro + environment: + MYSQL_ROOT_PASSWORD: phorge-dev + app: + build: ./application + ports: + - "${PHORGE_WEB_PORT:-80}:80" + - "${PHORGE_SSH_PORT:-22280}:22280" + environment: + SQL_HOST: db + SQL_PORT: 3306 + SQL_USER: root + SQL_PASSWORD: phorge-dev + BASE_URI: "${PHORGE_BASE_URI:-http://phorge.localhost/}" + volumes: + - "./.vscode:/srv/phorge/.vscode" + - "..:/srv/phorge/gantt" + - "./application/startup.sh:/startup.sh" + - "./application/setup.php:/srv/phorge/phorge/setup.php" diff --git a/.devcontainer/mysql/custom.cnf b/.devcontainer/mysql/custom.cnf new file mode 100644 index 0000000..e716fac --- /dev/null +++ b/.devcontainer/mysql/custom.cnf @@ -0,0 +1,5 @@ +[mysqld] +sql_mode=STRICT_ALL_TABLES +max_allowed_packet=33554432 +innodb_buffer_pool_size=1600M +local_infile=0 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ad4da41 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 80 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b193c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.phutil_module_cache diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/src/__phutil_library_init__.php b/src/__phutil_library_init__.php new file mode 100644 index 0000000..f1d0ae2 --- /dev/null +++ b/src/__phutil_library_init__.php @@ -0,0 +1,3 @@ + 2, + 'class' => array( + 'GanttApplication' => 'gantt/application/GanttApplication.php', + ), + 'function' => array(), + 'xmap' => array( + 'GanttApplication' => 'PhabricatorApplication', + ), +)); diff --git a/src/gantt/application/GanttApplication.php b/src/gantt/application/GanttApplication.php new file mode 100644 index 0000000..2d89c37 --- /dev/null +++ b/src/gantt/application/GanttApplication.php @@ -0,0 +1,7 @@ +