-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
pre-signed download urls for password protected public links #38376
Conversation
27c4700
to
9fc9ea8
Compare
return \hash_hmac('sha512/256', \implode('|', [$this->token, $this->fileName, $this->validUntil]), $this->signingKey, false); | ||
} | ||
|
||
public function verify($signature) { |
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.
Doesn't seem to add much value... I mean, you could just call the "get" method and compare it outside. Any future plan to make this verification more complex? That could justify this method.
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.
Yes you are right. The idea behind it was just to have a nice API.
$signature = new PublicShareSignature($share->getToken(), $node->getName(), $validUntil, $key);
if ($signature->verify($urlSignature)) {
...
vs.
$signature = new PublicShareSignature($share->getToken(), $node->getName(), $validUntil, $key);
if ($signature->get() == $urlSignature) {
...
It doesn't add much value and won't get any more complex in the future so I'm good with deleting the method and comparing the hash outside.
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.
Ok, just remember that ===
is always preferred. If you use ==
, include a comment explaining the reason in order to prevent changing it later.
$this->signingKey = $signingKey; | ||
} | ||
|
||
public function get() { |
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.
In general, I prefer to avoid too generic method names. It will be more difficult to find where this method is being used. getSignature
or getShareSignature
will be easier to find
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.
I agree with it potentially being hard to find.
Though if we change the name from get
to getSignature
then I would change the class as well.
Currently the usage looks like:
$signature = new PublicShareSignature($share->getToken(), $node->getName(), $validUntil, $key);
$signature->get();
By changing the method to getSignature
it would look wrong.
$signature = new PublicShareSignature($share->getToken(), $node->getName(), $validUntil, $key);
$signature->getSignature();
So how do you find this:
$signer = new PublicShareSigner($share->getToken(), $node->getName(), $validUntil, $key);
$signer->createSignature();
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.
"create" doesn't necessarily imply returning a value. You could create the signature, keep it inside the class, and return "true" or "false" to indicate if the signature was created successfully.
Anyway, I don't want to overcomplicate this, so I'm fine if you want to keep the "createSignature" name as long as it's properly documented and explained in the PHPDoc.
By changing the method to getSignature it would look wrong.
I partially agree. It looks wrong because that's the only method the object has. However, it doesn't look bad if you have a signature object with multiple methods, being one of them a method to return the raw or stringified signature.
9fc9ea8
to
901d87e
Compare
I converted the PR to a draft because I noticed a bug when sharing a folder. |
b9fa135
to
759b637
Compare
759b637
to
3c29599
Compare
So folder shares work now. |
$shared_resource_path = '/' . $share->getNode()->getName(); | ||
} | ||
$s = new PublicShareSigner($share->getToken(), $shared_resource_path, $validUntil, $key); | ||
return $path . '?signature=' . $s->getSignature() . '&expires=' . \urlencode($validUntil->format(\DateTime::ATOM)); |
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.
I assume the date format is consistent with the rest of the code. If not, there are 2 options: either change it for consistency or include a comment explaining.
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.
Well, there is no 'one' date format. In the code I found usages of ATOM
, ISO8601
, RFC2822
.
I chose ATOM
because of this: https://www.php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601
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.
Yes, we should have only one, but it seems we don't... at least we can change this one later without problems.
3c29599
to
30802b0
Compare
To support clients which don't use cookies I implemented pre-signed urls for password protected public links. The share password is used as the signing key and the signed url is then added to the propfind response in the field `downloadURL` which was added before but never used. This change allows owncloud Web to implement a more efficient download mechanism for password protected link shares.
30802b0
to
6ea3fb0
Compare
Kudos, SonarCloud Quality Gate passed! |
Description
When a propfind request is done for a password protected public link share and the property
'{http://owncloud.org/ns}downloadURL'
is requested, then a signed url is created and sent to the client as the value of that property.The downloadURL property was added some time ago but haven't been used since because the demand disappeared. So I think using this property should be fine.
Related Issue
Motivation and Context
To support clients which don't use cookies I implemented pre-signed urls
for password protected public links. The share password is used as the
signing key and the signed url is then added to the propfind response in
the field
downloadURL
which was added before but never used. Thischange allows owncloud Web to implement a more efficient download
mechanism for password protected link shares.
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: