diff options
| author | David Siegfried <david.siegfried@uni-vechta.de> | 2025-05-27 14:28:38 +0200 |
|---|---|---|
| committer | David Siegfried <david.siegfried@uni-vechta.de> | 2025-09-12 14:19:48 +0200 |
| commit | 61ca2f2a3fc71afed3550b19141bb9fededa3011 (patch) | |
| tree | 8fb7dcf5591c000795c168c1a77f7606a6e51a23 /lib/classes | |
| parent | cc9dbbccb76f32066f153b7635193cbd07efdd16 (diff) | |
add deeplinks
Diffstat (limited to 'lib/classes')
| -rw-r--r-- | lib/classes/Context.php | 48 | ||||
| -rw-r--r-- | lib/classes/JsonApi/RouteMap.php | 9 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Routes/ShortUrls/Authority.php | 27 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Routes/ShortUrls/ShortUrlCreate.php | 58 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Routes/ShortUrls/ShortUrlDelete.php | 38 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Routes/ShortUrls/ShortUrlShow.php | 20 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Routes/ShortUrls/ShortUrlUpdate.php | 48 | ||||
| -rw-r--r-- | lib/classes/JsonApi/SchemaMap.php | 3 | ||||
| -rw-r--r-- | lib/classes/JsonApi/Schemas/ShortUrl.php | 61 |
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; + } +} |
