aboutsummaryrefslogtreecommitdiff
path: root/lib/classes
diff options
context:
space:
mode:
authorDavid Siegfried <david.siegfried@uni-vechta.de>2025-05-27 14:28:38 +0200
committerDavid Siegfried <david.siegfried@uni-vechta.de>2025-09-12 14:19:48 +0200
commit61ca2f2a3fc71afed3550b19141bb9fededa3011 (patch)
tree8fb7dcf5591c000795c168c1a77f7606a6e51a23 /lib/classes
parentcc9dbbccb76f32066f153b7635193cbd07efdd16 (diff)
add deeplinks
Diffstat (limited to 'lib/classes')
-rw-r--r--lib/classes/Context.php48
-rw-r--r--lib/classes/JsonApi/RouteMap.php9
-rw-r--r--lib/classes/JsonApi/Routes/ShortUrls/Authority.php27
-rw-r--r--lib/classes/JsonApi/Routes/ShortUrls/ShortUrlCreate.php58
-rw-r--r--lib/classes/JsonApi/Routes/ShortUrls/ShortUrlDelete.php38
-rw-r--r--lib/classes/JsonApi/Routes/ShortUrls/ShortUrlShow.php20
-rw-r--r--lib/classes/JsonApi/Routes/ShortUrls/ShortUrlUpdate.php48
-rw-r--r--lib/classes/JsonApi/SchemaMap.php3
-rw-r--r--lib/classes/JsonApi/Schemas/ShortUrl.php61
9 files changed, 298 insertions, 14 deletions
diff --git a/lib/classes/Context.php b/lib/classes/Context.php
index 1bc2623..c73b58b 100644
--- a/lib/classes/Context.php
+++ b/lib/classes/Context.php
@@ -204,8 +204,6 @@ class Context
*/
public static function set($id)
{
- global $perm;
-
self::close();
self::loadContext($id);
@@ -219,32 +217,40 @@ class Context
URLHelper::addLinkParam('cid', $GLOBALS['SessionSeminar']);
- if (self::isCourse()) {
- $course = self::get();
+ $context = self::get();
+ if ($context instanceof Course) {
// check if current user can access the object
- if (!$perm->get_studip_perm($course['Seminar_id'])) {
- if ($course['lesezugriff'] > 0 || !Config::get()->ENABLE_FREE_ACCESS) {
+ if (!$GLOBALS['perm']->get_studip_perm($context->id)) {
+ if ($context->lesezugriff > 0 || !Config::get()->ENABLE_FREE_ACCESS) {
// redirect to login page if user is not logged in
if (!User::findCurrent()) {
throw new LoginException();
}
- if (!$perm->get_studip_perm($course['Seminar_id'])) {
- throw new AccessDeniedException();
+ if (!$GLOBALS['perm']->get_studip_perm($context->id && !match_route('dispatch.php/course/details'))) {
+ PageLayout::postWarning(_('Sie sind noch nich eingetragen. Bitte prüfen Sie die Anmelderegeln!'));
+ $url = URLHelper::getURL(
+ 'dispatch.php/course/details',
+ [
+ 'cid' => $context->id,
+ ]
+ );
+ header('Location: ' . $url);
+ die;
}
}
}
// if the aux data is forced for this seminar forward all user that havent made an input to this site
- if ($course['aux_lock_rule_forced']
- && !$perm->have_studip_perm('tutor', $course['Seminar_id'])
+ if ($context->aux_lock_rule_forced
+ && !$GLOBALS['perm']->have_studip_perm('tutor', $context->id)
&& !match_route('dispatch.php/course/members/additional_input')
&& !match_route('dispatch.php/course/change_view/*'))
{
$count = DatafieldEntryModel::countBySql(
'range_id = ? AND sec_range_id = ?',
- [$GLOBALS['user']->id, $course['Seminar_id']]
+ [$GLOBALS['user']->id, $context->id]
);
if (!$count) {
header('Location: ' . URLHelper::getURL('dispatch.php/course/members/additional_input'));
@@ -252,21 +258,35 @@ class Context
die;
}
}
- } else if (self::isInstitute()) {
+ } else if ($context instanceof Institute) {
// check if current user can access the object
$no_access = (!Config::get()->ENABLE_FREE_ACCESS ||
(Config::get()->ENABLE_FREE_ACCESS == 'courses_only'))
- && !$perm->have_perm('user');
+ && !$GLOBALS['perm']->have_perm('user');
+
if ($no_access) {
// redirect to login page if user is not logged in
if (!User::findCurrent()) {
throw new LoginException();
}
- if (!$perm->have_perm('user')) {
+ if (!$GLOBALS['perm']->have_perm('user')) {
throw new AccessDeniedException();
}
}
+
+
+ if (!$GLOBALS['perm']->get_studip_perm(self::getId()) && !match_route('dispatch.php/institute/overview')) {
+ PageLayout::postWarning(_('Sie sind zu dieser Einrichtung nicht zugeordnet!'));
+ $url = URLHelper::getURL(
+ 'dispatch.php/institute/overview',
+ [
+ 'cid' => $context->id,
+ ]
+ );
+ header('Location: ' . $url);
+ die;
+ }
}
}
diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php
index ca53a4a..865ddd8 100644
--- a/lib/classes/JsonApi/RouteMap.php
+++ b/lib/classes/JsonApi/RouteMap.php
@@ -142,6 +142,7 @@ class RouteMap
$this->addAuthenticatedThemesRoutes($group);
$this->addAuthenticatedUserFilterRoutes($group);
$this->addAuthenticatedWikiRoutes($group);
+ $this->addAuthenticatedShortUrlRoutes($group);
}
/**
@@ -803,6 +804,14 @@ class RouteMap
}
+ private function addAuthenticatedShortUrlRoutes(RouteCollectorProxy $group): void
+ {
+ $group->get('/short-urls', Routes\ShortUrls\ShortUrlShow::class);
+ $group->post('/short-urls', Routes\ShortUrls\ShortUrlCreate::class);
+ $group->patch('/short-urls/{id}', Routes\ShortUrls\ShortUrlUpdate::class);
+ $group->delete('/short-urls/{id}', Routes\ShortUrls\ShortUrlDelete::class);
+ }
+
private function addRelationship(RouteCollectorProxy $group, string $url, string $handler): void
{
$group->map(['GET', 'PATCH', 'POST', 'DELETE'], $url, $handler);
diff --git a/lib/classes/JsonApi/Routes/ShortUrls/Authority.php b/lib/classes/JsonApi/Routes/ShortUrls/Authority.php
new file mode 100644
index 0000000..e40d518
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/ShortUrls/Authority.php
@@ -0,0 +1,27 @@
+<?php
+namespace JsonApi\Routes\ShortUrls;
+
+use User;
+
+final class Authority
+{
+ public static function canCreateShortUrl(User $user): bool
+ {
+ return true;
+ }
+
+ public static function canAccessShortUrl(User $user, \ShortUrl $short_url): bool
+ {
+ return $user->id === $short_url->user_id;
+ }
+
+ public static function canUpdateShortUrl(User $user, \ShortUrl $short_url): bool
+ {
+ return self::canAccessShortUrl($user, $short_url);
+ }
+
+ public static function canDeleteShortUrl(User $user, \ShortUrl $short_url): bool
+ {
+ return self::canUpdateShortUrl($user, $short_url);
+ }
+}
diff --git a/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlCreate.php b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlCreate.php
new file mode 100644
index 0000000..db2a856
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlCreate.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace JsonApi\Routes\ShortUrls;
+
+use JsonApi\Errors\AuthorizationFailedException;
+use JsonApi\Errors\ConflictException;
+use JsonApi\JsonApiController;
+use JsonApi\Routes\ValidationTrait;
+use Psr\Http\Message\{
+ ResponseInterface as Response,
+ ServerRequestInterface as Request
+};
+
+final class ShortUrlCreate extends JsonApiController
+{
+ use ValidationTrait;
+
+ public function __invoke(Request $request, Response $response, $args): Response
+ {
+ $user = $this->getUser($request);
+
+ if (!Authority::canCreateShortUrl($user)) {
+ throw new AuthorizationFailedException();
+ }
+
+
+ $json = $this->validate($request, $args);
+
+ if (\ShortUrl::countBySql('path = ? AND user_id = ?', [ $json['data']['attributes']['path'], $user->id]) > 0) {
+ throw new ConflictException(_('Sie haben für diese Seite bereits eine Kurz-URL erstellt!'));
+ }
+
+ if (\ShortUrl::countBySql('alias = ?', [ $json['data']['attributes']['alias']])) {
+ throw new ConflictException(_('Sie haben für diese Seite bereits eine Kurz-URL erstellt!'));
+ }
+
+ $short_url = \ShortUrl::create([
+ 'path' => $json['data']['attributes']['path'],
+ 'alias' => $json['data']['attributes']['alias'],
+ 'user_id' => $user->id,
+ ]);
+
+ return $this->getContentResponse($short_url);
+ }
+
+ protected function validateResourceDocument($json, $data)
+ {
+ if (!self::arrayHas($json, 'data.attributes.path')) {
+ return 'No url for the short-url defined';
+ }
+
+ if (!trim(self::arrayGet($json, 'data.attributes.alias'))) {
+ return 'No alias for the short-url defined';
+ }
+
+ return null;
+ }
+}
diff --git a/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlDelete.php b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlDelete.php
new file mode 100644
index 0000000..a798d97
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlDelete.php
@@ -0,0 +1,38 @@
+<?php
+namespace JsonApi\Routes\ShortUrls;
+
+use JsonApi\Errors\RecordNotFoundException;
+
+use JsonApi\Errors\AuthorizationFailedException;
+use JsonApi\JsonApiController;
+use JsonApi\Routes\ShortUrls\Authority;
+use Psr\Http\Message\{
+ ResponseInterface as Response,
+ ServerRequestInterface as Request
+};
+
+class ShortUrlDelete extends JsonApiController
+{
+ /**
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function __invoke(Request $request, Response $response, $args)
+ {
+ $short_url = \ShortUrl::find($args['id']);
+
+ if ($short_url['id'] !== $args['id']) {
+ throw new RecordNotFoundException();
+ }
+
+ $user = $this->getUser($request);
+
+ if (!Authority::canDeleteShortUrl($user, $short_url)) {
+ throw new AuthorizationFailedException();
+ }
+
+ $short_url->delete();
+
+ return $this->getCodeResponse(204);
+ }
+
+}
diff --git a/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlShow.php b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlShow.php
new file mode 100644
index 0000000..ad77ebe
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlShow.php
@@ -0,0 +1,20 @@
+<?php
+namespace JsonApi\Routes\ShortUrls;
+
+use JsonApi\JsonApiController;
+use Psr\Http\Message\{
+ ResponseInterface as Response,
+ ServerRequestInterface as Request
+};
+
+final class ShortUrlShow extends JsonApiController
+{
+ public function __invoke(Request $request, Response $response, $args): Response
+ {
+ $user = $this->getUser($request);
+
+ $short_urls = \ShortURL::findBySql('user_id = ? ORDER BY `alias` ASC', [$user->id]);
+
+ return $this->getContentResponse($short_urls);
+ }
+}
diff --git a/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlUpdate.php b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlUpdate.php
new file mode 100644
index 0000000..f3eec23
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/ShortUrls/ShortUrlUpdate.php
@@ -0,0 +1,48 @@
+<?php
+namespace JsonApi\Routes\ShortUrls;
+
+use JsonApi\Errors\RecordNotFoundException;
+use JsonApi\Errors\AuthorizationFailedException;
+use JsonApi\JsonApiController;
+use JsonApi\Routes\ValidationTrait;
+use Psr\Http\Message\{
+ ResponseInterface as Response,
+ ServerRequestInterface as Request
+};
+
+final class ShortUrlUpdate extends JsonApiController
+{
+ use ValidationTrait;
+
+ public function __invoke(Request $request, Response $response, $args): Response
+ {
+ $user = $this->getUser($request);
+
+ $short_url = \ShortUrl::find($args['id']);
+
+ if ($short_url['id'] !== $args['id']) {
+ throw new RecordNotFoundException();
+ }
+
+ if (!Authority::canUpdateShortUrl($user, $short_url)) {
+ throw new AuthorizationFailedException();
+ }
+
+
+ $json = $this->validate($request);
+
+ $short_url->alias = $json['data']['attributes']['alias'];
+ $short_url->store();
+
+ return $this->getContentResponse($short_url);
+ }
+
+ protected function validateResourceDocument($json, $data)
+ {
+ if (!self::arrayHas($json, 'data.attributes.alias')) {
+ return 'No alias for the short-url defined';
+ }
+
+ return null;
+ }
+}
diff --git a/lib/classes/JsonApi/SchemaMap.php b/lib/classes/JsonApi/SchemaMap.php
index d45c6a7..7432abc 100644
--- a/lib/classes/JsonApi/SchemaMap.php
+++ b/lib/classes/JsonApi/SchemaMap.php
@@ -2,6 +2,8 @@
namespace JsonApi;
+use JsonApi\Schemas\ShortUrl;
+
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
@@ -102,6 +104,7 @@ class SchemaMap
\Courseware\Unit::class => Schemas\Courseware\Unit::class,
\Courseware\UserDataField::class => Schemas\Courseware\UserDataField::class,
\Courseware\UserProgress::class => Schemas\Courseware\UserProgress::class,
+ \ShortUrl::class => Schemas\ShortUrl::class,
];
}
}
diff --git a/lib/classes/JsonApi/Schemas/ShortUrl.php b/lib/classes/JsonApi/Schemas/ShortUrl.php
new file mode 100644
index 0000000..317a3a1
--- /dev/null
+++ b/lib/classes/JsonApi/Schemas/ShortUrl.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace JsonApi\Schemas;
+
+use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
+use Neomerx\JsonApi\Schema\Link;
+
+final class ShortUrl extends SchemaProvider
+{
+ public const TYPE = 'short-urls';
+ public const REL_USER = 'user';
+
+ /**
+ * @param \Clipboard $resource
+ */
+ public function getId($resource): ?string
+ {
+ return (string)$resource->id;
+ }
+
+ /**
+ * @param \Clipboard $resource
+ */
+ public function getAttributes($resource, ContextInterface $context): iterable
+ {
+ return [
+ 'alias' => $resource->alias,
+ 'path' => $resource->path,
+ 'mkdate' => date('c', $resource->mkdate),
+ 'chdate' => date('c', $resource->chdate),
+ ];
+ }
+
+ /**
+ * @param \ShortUrl $resource
+ */
+ public function getRelationships($resource, ContextInterface $context): iterable
+ {
+ $relationships = [];
+
+ $isPrimary = $context->getPosition()->getLevel() === 0;
+ if ($isPrimary) {
+ $relationships = $this->getUserRelationship($relationships, $resource, $this->shouldInclude($context, self::REL_USER));
+ }
+
+
+ return $relationships;
+ }
+
+ private function getUserRelationship(array $relationships, \ShortUrl $short_url, bool $includeData): array
+ {
+ $relationships[self::REL_USER] = [
+ self::RELATIONSHIP_LINKS => [
+ Link::RELATED => $this->createLinkToResource($short_url->user),
+ ],
+ self::RELATIONSHIP_DATA => $includeData ? $short_url->user : \User::build(['id' => $short_url->user_id], false),
+ ];
+
+ return $relationships;
+ }
+}