summaryrefslogtreecommitdiffstats
path: root/modules-available/sysconfig/inc/configmodule/shibauth.inc.php
blob: 801b30bf0c1f399294b682b1658e9bec85062328 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php

ConfigModule::registerModule(
	ConfigModule_ShibAuth::MODID, // ID
	Dictionary::translateFile('config-module', 'shibauth_title'), // Title
	Dictionary::translateFile('config-module', 'shibauth_description'), // Description
	Dictionary::translateFile('config-module', 'group_authentication'), // Group
	false, // Only one per config?
	310 // Sort order
);

class ConfigModule_ShibAuth extends ConfigModule
{
	const MODID = 'ShibAuth';
	const VERSION = 1;

	protected function generateInternal(string $tgz, ?string $parent)
	{
		/* Validate if all data are available */
		if (!$this->validateConfig())
			return false;

		return Taskmanager::submit('MakeTarball', array(
			'files' => $this->getFileArray(),
			'destination' => $tgz,
			'parentTask' => $parent,
		), false);
	}

	protected function moduleVersion(): int
	{
		return self::VERSION;
	}

	protected function validateConfig(): bool
	{
		return isset($this->moduleData['browser']) || isset($this->moduleData['qrcode'])
			|| !empty($this->moduleData['idp']);
	}

	public function setData(string $key, $value): bool
	{
		switch ($key) {
		case 'browser':
		case 'qrcode':
		case 'userlogin':
		case 'idp':
		case 'regs':
			break;
		case 'entitlements':
			$value = str_replace(["\r", "\n", " ", "\t"], ';', $value);
			break;
		default:
			return false;
		}
		$this->moduleData[$key] = $value;
		return true;
	}

	public function allowDownload(): bool
	{
		return false;
	}

	/**
	 * Creates a map with filepath => file content
	 * @return array{"/opt/openslx/pam/shibboleth/whitelist/shib-$id.idp": string,
	 *    "/etc/lightdm/qt-lightdm-greeter.conf.d/shib-$id.conf": string,
	 *    "/opt/openslx/pam/shibboleth/whitelist/shib-$id.suffix": string}
	 */
	private function getFileArray(): array
	{
		$id = $this->id();
		$url = CONFIG_SHIB_CLIENT_URL;
		$browser = '';
		$qrcode = '';
		$userlogin = '';
		if ($this->moduleData['browser'] ?? false) {
			$browser = "shib-session-enabled = true";
		}
		if ($this->moduleData['qrcode'] ?? false) {
			$qrcode = "qr-session-enabled = true";
		}
		if (!($this->moduleData['userlogin'] ?? true)) {
			$userlogin = "user-session-enabled = false";
		}
		return [
			"/etc/lightdm/qt-lightdm-greeter.conf.d/shib-$id.conf" => <<<EOF
[General]
shib-url = $url
$browser
$qrcode
$userlogin
EOF,
			"/opt/openslx/pam/shibboleth/whitelist/shib-$id.idp" => $this->generateIdpList(),
			"/opt/openslx/pam/shibboleth/whitelist/shib-$id.suffix" => $this->generateSuffixList(),
		];
	}

	/**
	 * Generate plain-text file of suffixes belonging to all enabled entities.
	 * Used by pam-part on client to verify login.
	 */
	private function generateSuffixList(): string
	{
		$idp2suffix = Shib::getIdp2SuffixList();
		if ($idp2suffix === null)
			return '';
		// Explode registrar shortcuts
		if (is_array($this->moduleData['regs'] ?? 0)) {
			$idps = Shib::explodeRegistrars($this->moduleData['regs']);
		} else {
			$idps = [];
		}
		if (is_array($this->moduleData['idp'])) {
			$idps = array_merge($idps, $this->moduleData['idp']);
		}
		// Build
		$return = '';
		foreach ($idps as $idp) {
			if (empty($idp2suffix[$idp]))
				continue;
			$return .= implode("\n", $idp2suffix[$idp]['suffix']) . "\n";
		}
		return $return;
	}

	/**
	 * Generates a list of Identity Providers (IdPs) based on the module's configuration data.
	 * Expands registrar data and merges with IdP data into a single list.
	 * If one or more entitlements are required, they're put on the first line.
	 *
	 * @return string A newline-separated string containing the list of IdPs.
	 */
	private function generateIdpList(): string
	{
		$idps = [];
		if (!empty($this->moduleData['entitlements'])) {
			$idps[] = '# entitlements=' . $this->moduleData['entitlements'];
		}
		if (is_array($this->moduleData['regs'] ?? 0)) {
			$idps = array_merge($idps, Shib::explodeRegistrars($this->moduleData['regs']));
		}
		if (is_array($this->moduleData['idp'])) {
			$idps = array_merge($idps, $this->moduleData['idp']);
		}
		return implode("\n", $idps) . "\n";
	}

}