Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F262006
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/bin/quickstart.sh b/bin/quickstart.sh
index f48ff50c..d63858f6 100755
--- a/bin/quickstart.sh
+++ b/bin/quickstart.sh
@@ -1,141 +1,131 @@
#!/bin/bash
set -e
function die() {
echo "$1"
exit 1
}
rpm -qv docker-compose >/dev/null 2>&1 || \
test ! -z "$(which docker-compose 2>/dev/null)" || \
die "Is docker-compose installed?"
test ! -z "$(grep 'systemd.unified_cgroup_hierarchy=0' /proc/cmdline)" || \
die "systemd containers only work with cgroupv1 (use 'grubby --update-kernel=ALL --args=\"systemd.unified_cgroup_hierarchy=0\"' and a reboot to fix)"
base_dir=$(dirname $(dirname $0))
export DOCKER_BUILDKIT=0
docker-compose down --remove-orphans
docker volume rm kolab_mariadb || :
docker volume rm kolab_imap || :
docker volume rm kolab_ldap || :
# We can't use the following artisan commands because it will just block if redis is unavailable:
# src/artisan octane:stop >/dev/null 2>&1 || :
# src/artisan horizon:terminate >/dev/null 2>&1 || :
# we therefore just kill all artisan processes running.
pkill -9 -f artisan || :
pkill -9 -f swoole || :
bin/regen-certs
docker-compose build coturn kolab mariadb meet pdns proxy redis haproxy
docker-compose up -d coturn kolab mariadb meet pdns redis
# Workaround until we have docker-compose --wait (https://github.com/docker/compose/pull/8777)
function wait_for_container {
container_id="$1"
container_name="$(docker inspect "${container_id}" --format '{{ .Name }}')"
echo "Waiting for container: ${container_name} [${container_id}]"
waiting_done="false"
while [[ "${waiting_done}" != "true" ]]; do
container_state="$(docker inspect "${container_id}" --format '{{ .State.Status }}')"
if [[ "${container_state}" == "running" ]]; then
health_status="$(docker inspect "${container_id}" --format '{{ .State.Health.Status }}')"
echo "${container_name}: container_state=${container_state}, health_status=${health_status}"
if [[ ${health_status} == "healthy" ]]; then
waiting_done="true"
fi
else
echo "${container_name}: container_state=${container_state}"
waiting_done="true"
fi
sleep 1;
done;
}
if [ "$1" == "--nodev" ]; then
echo "starting everything in containers"
docker-compose -f docker-compose.build.yml build swoole
docker-compose build webapp
docker-compose up -d webapp proxy haproxy
wait_for_container 'kolab-webapp'
exit 0
fi
echo "Starting the development environment"
rpm -qv composer >/dev/null 2>&1 || \
test ! -z "$(which composer 2>/dev/null)" || \
die "Is composer installed?"
rpm -qv npm >/dev/null 2>&1 || \
test ! -z "$(which npm 2>/dev/null)" || \
die "Is npm installed?"
rpm -qv php >/dev/null 2>&1 || \
test ! -z "$(which php 2>/dev/null)" || \
die "Is php installed?"
rpm -qv php-ldap >/dev/null 2>&1 || \
test ! -z "$(php --ini | grep ldap)" || \
die "Is php-ldap installed?"
rpm -qv php-mysqlnd >/dev/null 2>&1 || \
test ! -z "$(php --ini | grep mysql)" || \
die "Is php-mysqlnd installed?"
test ! -z "$(php --modules | grep swoole)" || \
die "Is swoole installed?"
# Ensure the containers we depend on are fully started
wait_for_container 'kolab'
wait_for_container 'kolab-redis'
pushd ${base_dir}/src/
rm -rf vendor/ composer.lock
php -dmemory_limit=-1 $(which composer) install
npm install
find bootstrap/cache/ -type f ! -name ".gitignore" -delete
./artisan key:generate
./artisan clear-compiled
./artisan cache:clear
./artisan horizon:install
-if [ ! -f storage/oauth-public.key -o ! -f storage/oauth-private.key ]; then
- ./artisan passport:keys --force
-fi
-
-cat >> .env << EOF
-PASSPORT_PRIVATE_KEY="$(cat storage/oauth-private.key)"
-PASSPORT_PUBLIC_KEY="$(cat storage/oauth-public.key)"
-EOF
-
-
if rpm -qv chromium 2>/dev/null; then
chver=$(rpmquery --queryformat="%{VERSION}" chromium | awk -F'.' '{print $1}')
./artisan dusk:chrome-driver ${chver}
fi
if [ ! -f 'resources/countries.php' ]; then
./artisan data:countries
fi
npm run dev
popd
pushd ${base_dir}/src/
rm -rf database/database.sqlite
./artisan db:ping --wait
php -dmemory_limit=512M ./artisan migrate:refresh --seed
./artisan data:import || :
nohup ./artisan octane:start --host=$(grep OCTANE_HTTP_HOST .env | tail -n1 | sed "s/OCTANE_HTTP_HOST=//") > octane.out &
nohup ./artisan horizon > horizon.out &
popd
docker-compose up --no-deps -d proxy haproxy
diff --git a/config.demo/src/database/seeds/AppKeySeeder.php b/config.demo/src/database/seeds/AppKeySeeder.php
new file mode 100644
index 00000000..4554bf5d
--- /dev/null
+++ b/config.demo/src/database/seeds/AppKeySeeder.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Database\Seeds;
+
+use Laravel\Passport\Passport;
+use Illuminate\Database\Seeder;
+use Illuminate\Encryption\Encrypter;
+
+class AppKeySeeder extends Seeder
+{
+ /**
+ * Run the database seeds.
+ *
+ * This emulates './artisan key:generate'
+ *
+ * @return void
+ */
+ public function run()
+ {
+ $key = $this->generateRandomKey();
+ $this->writeNewEnvironmentFileWith($key);
+ }
+
+ /**
+ * Generate a random key for the application.
+ *
+ * @return string
+ */
+ protected function generateRandomKey()
+ {
+ return 'base64:' . base64_encode(
+ Encrypter::generateKey(\config('app.cipher'))
+ );
+ }
+
+ /**
+ * Write a new environment file with the given key.
+ *
+ * @param string $key
+ * @return void
+ */
+ protected function writeNewEnvironmentFileWith($key)
+ {
+ file_put_contents(\app()->environmentFilePath(), preg_replace(
+ $this->keyReplacementPattern(),
+ 'APP_KEY=' . $key,
+ file_get_contents(\app()->environmentFilePath())
+ ));
+ }
+
+ /**
+ * Get a regex pattern that will match env APP_KEY with any random key.
+ *
+ * @return string
+ */
+ protected function keyReplacementPattern()
+ {
+ $escaped = preg_quote('=' . \config('app.key'), '/');
+ return "/^APP_KEY{$escaped}/m";
+ }
+}
+
diff --git a/config.demo/src/database/seeds/DatabaseSeeder.php b/config.demo/src/database/seeds/DatabaseSeeder.php
index cebfef72..bef5f2d2 100644
--- a/config.demo/src/database/seeds/DatabaseSeeder.php
+++ b/config.demo/src/database/seeds/DatabaseSeeder.php
@@ -1,32 +1,34 @@
<?php
use Illuminate\Database\Seeder;
use Database\Seeds;
// phpcs:ignore
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call([
+ Seeds\AppKeySeeder::class,
+ Seeds\PassportSeeder::class,
Seeds\IP4NetSeeder::class,
Seeds\TenantSeeder::class,
Seeds\DiscountSeeder::class,
Seeds\DomainSeeder::class,
Seeds\SkuSeeder::class,
Seeds\PackageSeeder::class,
Seeds\PlanSeeder::class,
Seeds\PowerDNSSeeder::class,
Seeds\UserSeeder::class,
Seeds\OauthClientSeeder::class,
Seeds\ResourceSeeder::class,
Seeds\SharedFolderSeeder::class,
Seeds\MeetRoomSeeder::class,
]);
}
}
diff --git a/config.demo/src/database/seeds/PassportSeeder.php b/config.demo/src/database/seeds/PassportSeeder.php
new file mode 100644
index 00000000..4bc8aa1e
--- /dev/null
+++ b/config.demo/src/database/seeds/PassportSeeder.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Database\Seeds;
+
+use Laravel\Passport\Passport;
+use Illuminate\Database\Seeder;
+use Illuminate\Encryption\Encrypter;
+use phpseclib3\Crypt\RSA;
+
+class PassportSeeder extends Seeder
+{
+ /**
+ * Run the database seeds.
+ *
+ * This emulates:
+ * './artisan passport:keys --force'
+ * './artisan passport:client --password --name="Kolab Password Grant Client" --provider=users'
+ *
+ * @return void
+ */
+ public function run()
+ {
+ //First initialize the passport keys
+ [$publicKey, $privateKey] = [
+ Passport::keyPath('oauth-public.key'),
+ Passport::keyPath('oauth-private.key'),
+ ];
+ $key = RSA::createKey(4096);
+ file_put_contents($publicKey, (string) $key->getPublicKey());
+ file_put_contents($privateKey, (string) $key);
+
+ $this->writeNewEnvironmentFileWith('PASSPORT_PRIVATE_KEY', 'passport.private_key', $key);
+ $this->writeNewEnvironmentFileWith('PASSPORT_PUBLIC_KEY', 'passport.public_key', (string) $key->getPublicKey());
+
+ //Create a password grant client for the webapp
+ $secret = $this->generateRandomKey();
+
+ $client = Passport::client()->forceFill([
+ 'user_id' => null,
+ 'name' => "Kolab Password Grant Client",
+ 'secret' => $secret,
+ 'provider' => 'users',
+ 'redirect' => 'https://' . \config('app.website_domain'),
+ 'personal_access_client' => 0,
+ 'password_client' => 1,
+ 'revoked' => false,
+ ]);
+ $client->save();
+
+ $this->writeNewEnvironmentFileWith('PASSPORT_PROXY_OAUTH_CLIENT_ID', 'auth.proxy.client_id', $client->id);
+ $this->writeNewEnvironmentFileWith('PASSPORT_PROXY_OAUTH_CLIENT_SECRET', 'auth.proxy.client_secret', $secret);
+ }
+
+ /**
+ * Generate a random key for the application.
+ *
+ * @return string
+ */
+ protected function generateRandomKey()
+ {
+ return base64_encode(
+ Encrypter::generateKey(\config('app.cipher'))
+ );
+ }
+
+ /**
+ * Write a new environment file with the given key.
+ *
+ * @param string $key
+ * @param string $configKey
+ * @param string $value
+ * @return void
+ */
+ protected function writeNewEnvironmentFileWith($key, $configKey, $value)
+ {
+ $path = \app()->environmentFilePath();
+ $count = 0;
+ $line = "{$key}=\"{$value}\"";
+ $result = preg_replace(
+ $this->keyReplacementPattern($key, \config($configKey)),
+ $line,
+ file_get_contents($path),
+ -1,
+ $count
+ );
+ //Append if it doesn't exist
+ if ($count == 0) {
+ $result = $result . "\n$line";
+ }
+ file_put_contents($path, $result);
+ }
+
+ /**
+ * Get a regex pattern that will match env APP_KEY with any random key.
+ *
+ * @return string
+ */
+ protected function keyReplacementPattern($key, $value)
+ {
+ $escaped = preg_quote("={$value}", '/');
+ return "/^{$key}{$escaped}/m";
+ }
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Jun 27, 10:22 PM (3 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
201375
Default Alt Text
(10 KB)
Attached To
Mode
R2 kolab
Attached
Detach File
Event Timeline
Log In to Comment