Skip to content
Snippets Groups Projects
Commit e9a6f144 authored by Alexander Hinneburg's avatar Alexander Hinneburg
Browse files

initial commit

parents
No related branches found
No related tags found
No related merge requests found
pg-data/*
.env
# Docker-Container für Einführung in Datenbanken
Der Container installiert ein Postgres-DBMS in der Version 11.2 mit mehreren Übungsdatenbanken und die Adminer-Web-Applikation, um mit SQL auf diese Datenbanken zugreifen zu können.
## Installation
Zum Arbeiten mit Docker brauchen sie Administrator-Rechte oder sie müssen in der Gruppe `docker` sein.
1. Installieren sie [Docker Community Edition](https://docs.docker.com/install/) und [Docker-Compose](https://docs.docker.com/compose/install/).
2. Laden sie sich dieses Projekt auf ihren Computer, entpacken sie es und wechseln sie in das Verzeichnis `edb-pg-adm`.
3. Kopieren sie die Datei `env-example` nach `.env` und editieren sie `.env` um die Passwörter für den Datenbankzugriff zu setzen und den Port für die Adminer-Web-Applikation festzulegen.
4. Führen sie in dem Verzeichnis `edb-pg-adm` in einer Shell das folgende Kommando aus, um den Container zu starten
```
docker-compose up
```
Beim ersten Start werden die Container für Postgres und Adminer von [hub.docker.com](https://hub.docker.com) geladen und die Datenbanken in dem Unterverzeichnis `pg-data` angelegt.
## Arbeiten mit dem Docker-Container
Wenn der Docker-Container gestartet wurde (wie in Schritt 4 beschrieben) können mit einem Browser auf Adminer zu greifen. Wenn sie den Container auf ihren Computer installiert und den Port 80 gesetzt haben, ist der Link [http://localhost:80](http://localhost:80).
Sie können sich als der Nutzer `student_gast` mit dem Passwort einloggen, dass sie in der Datei `.env` vorgegeben haben.
In der Datenbank `postgres` sind folgende Datenbankschemata installiert:
- `student_public` mit den Tabellen aus der Vorlesung
- `empdept_public`
- `komponist`
- `maerchen`
- `presidents`
- `sakila`
- `auto_motorcycle`
version: '3.4'
services:
db:
image: postgres:alpine
container_name: postgres
restart: always
environment:
- POSTGRES_PASSWORD
- STUDENT_PASSWORD
volumes:
- "./pg-data:/var/lib/postgresql/data"
- "./init:/docker-entrypoint-initdb.d"
adminer:
build:
context: ./src
dockerfile: Dockerfile
restart: always
environment:
- ADMINER_PLUGINS=account-nolock-plugin
ports:
- ${ADMINER_PORT}:8080
# Change the settings to your need and rename this file to .env .
# Be careful, setting those passwords takes effect only when
# databases are created.
# The postgres-docker-container creates databases only if
# the pg_data directory is empty or not existing.
POSTGRES_PASSWORD=change-this!
STUDENT_PASSWORD=change-this-too!
# Access adminer over the specified port, e.g. http://localhost:80/
ADMINER_PORT=80
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE ROLE student
WITH
NOLOGIN
;
CREATE ROLE student_gast
WITH
LOGIN
PASSWORD '${STUDENT_PASSWORD}'
IN ROLE student
;
REVOKE ALL PRIVILEGES ON DATABASE postgres FROM student, student_gast;
GRANT CONNECT ON DATABASE postgres TO student;
REVOKE ALL ON SCHEMA public FROM public;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public, student, student_gast;
DROP SCHEMA public;
EOSQL
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "template1" <<-EOSQL
REVOKE ALL PRIVILEGES ON DATABASE template1 FROM student, student_gast;
REVOKE ALL ON SCHEMA public FROM public;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public, student, student_gast;
EOSQL
File added
File added
File added
File added
File added
File added
File added
from adminer:4.7.1
USER root:root
COPY account-nolock-plugin.php /var/www/html/plugins/
COPY plugin.php /var/www/html/plugins/
USER adminer:adminer
<?php
/** Disable account locking
*/
class AdminerNolock {
function bruteForceKey() {
// Return high resolution time
// to get for each call a different key.
// This effectively disables the locking mechanism
// that forces a wait time of 30 min after 30 failed
// login attempts. This could is needed in class room situations
// with all clients accessing adminer through the same IP
// to prevent locking adminer by single students.
// convert time to string by prefixing "t"
// as the caller expects a string.
return "t" . hrtime(true);
}
}
<?php
/** Adminer customization allowing usage of plugins
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerPlugin extends Adminer {
/** @access protected */
var $plugins;
function _findRootClass($class) { // is_subclass_of(string, string) is available since PHP 5.0.3
do {
$return = $class;
} while ($class = get_parent_class($class));
return $return;
}
/** Register plugins
* @param array object instances or null to register all classes starting by 'Adminer'
*/
function __construct($plugins) {
if ($plugins === null) {
$plugins = array();
foreach (get_declared_classes() as $class) {
if (preg_match('~^Adminer.~i', $class) && strcasecmp($this->_findRootClass($class), 'Adminer')) { //! can use interface
$plugins[$class] = new $class;
}
}
}
$this->plugins = $plugins;
//! it is possible to use ReflectionObject to find out which plugins defines which methods at once
}
function _callParent($function, $args) {
return call_user_func_array(array('parent', $function), $args);
}
function _applyPlugin($function, $args) {
foreach ($this->plugins as $plugin) {
if (method_exists($plugin, $function)) {
switch (count($args)) { // call_user_func_array() doesn't work well with references
case 0: $return = $plugin->$function(); break;
case 1: $return = $plugin->$function($args[0]); break;
case 2: $return = $plugin->$function($args[0], $args[1]); break;
case 3: $return = $plugin->$function($args[0], $args[1], $args[2]); break;
case 4: $return = $plugin->$function($args[0], $args[1], $args[2], $args[3]); break;
case 5: $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4]); break;
case 6: $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); break;
default: trigger_error('Too many parameters.', E_USER_WARNING);
}
if ($return !== null) {
return $return;
}
}
}
return $this->_callParent($function, $args);
}
function _appendPlugin($function, $args) {
$return = $this->_callParent($function, $args);
foreach ($this->plugins as $plugin) {
if (method_exists($plugin, $function)) {
$value = call_user_func_array(array($plugin, $function), $args);
if ($value) {
$return += $value;
}
}
}
return $return;
}
// appendPlugin
function dumpFormat() {
$args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args);
}
function dumpOutput() {
$args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args);
}
function editFunctions($field) {
$args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args);
}
// applyPlugin
function bruteForceKey() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function name() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function credentials() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function connectSsl() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function permanentLogin($create = false) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function serverName($server) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function database() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function schemas() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function databases($flush = true) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function queryTimeout() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function headers() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function csp() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function head() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function css() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function loginForm() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function loginFormField($name, $heading, $value) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function login($login, $password) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function tableName($tableStatus) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function fieldName($field, $order = 0) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectLinks($tableStatus, $set = "") {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function foreignKeys($table) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function backwardKeys($table, $tableName) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function backwardKeysPrint($backwardKeys, $row) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectQuery($query, $start, $failed = false) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function sqlCommandQuery($query) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function rowDescription($table) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function rowDescriptions($rows, $foreignKeys) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectLink($val, $field) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectVal($val, $link, $field, $original) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function editVal($val, $field) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function tableStructurePrint($fields) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function tableIndexesPrint($indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectColumnsPrint($select, $columns) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectSearchPrint($where, $columns, $indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectOrderPrint($order, $columns, $indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectLimitPrint($limit) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectLengthPrint($text_length) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectActionPrint($indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectCommandPrint() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectImportPrint() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectEmailPrint($emailFields, $columns) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectColumnsProcess($columns, $indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectSearchProcess($fields, $indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectOrderProcess($fields, $indexes) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectLimitProcess() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectLengthProcess() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectEmailProcess($where, $foreignKeys) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectQueryBuild($select, $where, $group, $order, $limit, $page) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function messageQuery($query, $time, $failed = false) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function editInput($table, $field, $attrs, $value) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function editHint($table, $field, $value) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function processInput($field, $value, $function = "") {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function dumpDatabase($db) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function dumpTable($table, $style, $is_view = 0) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function dumpData($table, $style, $query) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function dumpFilename($identifier) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function dumpHeaders($identifier, $multi_table = false) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function importServerPath() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function homepage() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function navigation($missing) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function databasesPrint($missing) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function tablesPrint($tables) {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment