-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Admin setting iframe #4373
base: main
Are you sure you want to change the base?
Changes from 4 commits
c0fe494
7e840f9
7fac5ca
104c780
a26cab5
cb707b1
4a62c88
d70c466
ce2ccba
e1f8021
cc91ef8
c2e7a19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -384,6 +384,25 @@ public function editOnlineTarget(int $fileId, ?string $target = null): RedirectR | |
#[PublicPage] | ||
public function token(int $fileId, ?string $shareToken = null, ?string $path = null, ?string $guestName = null): DataResponse { | ||
try { | ||
if ($fileId === -1 && $path !== null && str_starts_with($path, 'admin-settings/')) { | ||
$parts = explode('/', $path); | ||
$adminUserId = $parts[1] ?? $this->userId; // fallback if needed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems dangerous, we should always use Additionally we need to check if the user id is an admin (Can be done through https://github.com/nextcloud/server/blob/dff881544920f426b984f91b7bc8dece1f351342/lib/public/IGroupManager.php#L115 |
||
|
||
$docKey = $fileId . '_' . $this->config->getSystemValue('instanceid'); | ||
|
||
$wopi = $this->tokenManager->generateWopiToken($fileId, null, $adminUserId); | ||
|
||
$coolBaseUrl = $this->appConfig->getCollaboraUrlPublic(); | ||
$adminSettingsWopiSrc = $coolBaseUrl . '/browser/admin-settings.html?'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally this would be an URL that can be obtained from the discovery endpoint of Collabora, could be a separate app element for settings |
||
|
||
return new DataResponse([ | ||
'urlSrc' => $adminSettingsWopiSrc, | ||
'token' => $wopi->getToken(), | ||
'token_ttl' => $wopi->getExpiry(), | ||
]); | ||
} | ||
|
||
// Normal file handling (unchanged) | ||
$share = $shareToken ? $this->shareManager->getShareByToken($shareToken) : null; | ||
$file = $shareToken ? $this->getFileForShare($share, $fileId, $path) : $this->getFileForUser($fileId, $path); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,34 @@ public function generateFileToken($fileId, $owner, $editor, $version, $updatable | |
return $wopi; | ||
} | ||
|
||
public function generateUserSettingsToken($fileId, $owner, $editor, $version, $updatable, $serverHost, ?string $guestDisplayname = null, $hideDownload = false, $direct = false, $templateId = 0, $share = null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably can simplify the signature of this method a lot. Most of it is passed in as dummy/default values |
||
$token = $this->random->generate(32, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS); | ||
|
||
$wopi = Wopi::fromParams([ | ||
'fileid' => $fileId, | ||
'ownerUid' => $owner, | ||
'editorUid' => $editor, | ||
'version' => $version, | ||
'canwrite' => $updatable, | ||
'serverHost' => $serverHost, | ||
'token' => $token, | ||
'expiry' => $this->calculateNewTokenExpiry(), | ||
'guestDisplayname' => $guestDisplayname, | ||
'hideDownload' => $hideDownload, | ||
'direct' => $direct, | ||
'templateId' => $templateId, | ||
'remoteServer' => '', | ||
'remoteServerToken' => '', | ||
'share' => $share, | ||
'tokenType' => Wopi::TOKEN_TYPE_SETTING_AUTH | ||
]); | ||
|
||
/** @var Wopi $wopi */ | ||
$wopi = $this->insert($wopi); | ||
|
||
return $wopi; | ||
} | ||
|
||
public function generateInitiatorToken($uid, $remoteServer) { | ||
$token = $this->random->generate(32, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS); | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -46,11 +46,20 @@ public function __construct( | |||||
* @throws Exception | ||||||
*/ | ||||||
public function generateWopiToken(string $fileId, ?string $shareToken = null, ?string $editoruid = null, bool $direct = false): Wopi { | ||||||
[$fileId, , $version] = Helper::parseFileId($fileId); | ||||||
|
||||||
$owneruid = null; | ||||||
$hideDownload = false; | ||||||
$rootFolder = $this->rootFolder; | ||||||
|
||||||
if ($fileId == "-1") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Best always use strict comparison in PHP |
||||||
{ | ||||||
$editoruid = $this->userId; | ||||||
$serverHost = $this->urlGenerator->getAbsoluteURL('/'); | ||||||
return $this->wopiMapper->generateUserSettingsToken($fileId, $owneruid, $editoruid, 0, true, $serverHost, "", $hideDownload, $direct, 0, $shareToken); | ||||||
} | ||||||
|
||||||
[$fileId, , $version] = Helper::parseFileId($fileId); | ||||||
|
||||||
// if the user is not logged-in do use the sharers storage | ||||||
if ($shareToken !== null) { | ||||||
/** @var File $file */ | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<!-- CoolFrame.vue --> | ||
<template> | ||
<div> | ||
<form ref="form" | ||
:action="formAction" | ||
method="post" | ||
:target="iframeName"> | ||
<input type="hidden" name="access_token" :value="accessToken"> | ||
<input type="hidden" name="access_token_ttl" :value="accessTokenTTL"> | ||
<!-- TODO: Include any other necessary hidden inputs --> | ||
</form> | ||
<iframe :id="iframeName" | ||
:name="iframeName" | ||
class="cool-frame-iframe" | ||
:src="'about:blank'" | ||
frameborder="0" | ||
allowfullscreen /> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
|
||
import { getCoolServerUrl } from '../helpers/url.js' | ||
|
||
export default { | ||
name: 'CoolFrame', | ||
props: { | ||
endpoint: { | ||
type: String, | ||
required: true, | ||
}, | ||
publicWopiUrl: { | ||
type: String, | ||
required: true, | ||
}, | ||
accessToken: { | ||
type: String, | ||
required: true, | ||
}, | ||
accessTokenTTL: { | ||
type: [String, Number], | ||
required: true, | ||
}, | ||
}, | ||
data() { | ||
return { | ||
iframeName: 'coolFrameIframe', | ||
formAction: '', | ||
} | ||
}, | ||
mounted() { | ||
// Ensure publicWopiUrl is used to construct formAction | ||
if (this.publicWopiUrl) { | ||
this.formAction = getCoolServerUrl(this.publicWopiUrl) | ||
console.debug('Form action URL generated:', this.formAction) | ||
} else { | ||
console.error('wopiUrl prop is missing') | ||
} | ||
console.debug('Form action URL generated') | ||
// Submit the form to load the iframe content | ||
this.$nextTick(() => { | ||
if (this.$refs.form) { | ||
this.$refs.form.submit() | ||
} else { | ||
console.error('Form reference not found') | ||
} | ||
}) | ||
}, | ||
} | ||
</script> | ||
|
||
<style scoped> | ||
.cool-frame-iframe { | ||
width: 100%; | ||
height: 600px; | ||
border: none; | ||
} | ||
</style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can even extract this part, so we don't need to extend the token endpoint. This logic could be moved to the SettingsController and generate a token directly there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be safer as then we can be sure this can only be called by admins