mirror of
https://github.com/netzbegruenung/circles.git
synced 2024-04-30 02:44:52 +02:00
-orig_password +member_id
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
parent
2387bf1b78
commit
9f67aebd45
|
@ -40,6 +40,8 @@ use OCP\AppFramework\IAppContainer;
|
|||
use OCP\AppFramework\QueryException;
|
||||
use OCP\Util;
|
||||
|
||||
require_once __DIR__ . '/../../appinfo/autoload.php';
|
||||
|
||||
|
||||
class Application extends App {
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@ use OCP\Util;
|
|||
class FileSharingBroadcaster implements IBroadcaster {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var bool */
|
||||
private $initiated = false;
|
||||
|
||||
|
@ -233,14 +230,14 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
$password = $this->miscService->token(15);
|
||||
}
|
||||
|
||||
$sharesToken = $this->tokensRequest->generateTokenForMember($member, $share->getId());
|
||||
$sharesToken = $this->tokensRequest->generateTokenForMember($member, $share->getId(), $password);
|
||||
$mails = [$member->getUserId()];
|
||||
if ($member->getType() === Member::TYPE_CONTACT) {
|
||||
$mails = $this->getMailsFromContact($member->getUserId());
|
||||
}
|
||||
|
||||
foreach ($mails as $mail) {
|
||||
$this->sharedByMail($circle, $share, $mail, $sharesToken);
|
||||
$this->sharedByMail($circle, $share, $mail, $sharesToken, $password);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
@ -298,7 +295,12 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
|
||||
$recipient = $member->getUserId();
|
||||
if ($member->getType() === Member::TYPE_CONTACT) {
|
||||
$emails = $this->getArray('EMAIL', MiscService::getContactData($member->getUserId()));
|
||||
$data = MiscService::getContactData($member->getUserId());
|
||||
if (!array_key_exists('EMAIL', $data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$emails = $data['EMAIL'];
|
||||
if (empty($emails)) {
|
||||
return;
|
||||
}
|
||||
|
@ -392,8 +394,11 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
* @param IShare $share
|
||||
* @param string $email
|
||||
* @param SharesToken $sharesToken
|
||||
* @param string $password
|
||||
*/
|
||||
private function sharedByMail(Circle $circle, IShare $share, $email, SharesToken $sharesToken) {
|
||||
private function sharedByMail(
|
||||
Circle $circle, IShare $share, string $email, SharesToken $sharesToken, string $password
|
||||
) {
|
||||
// genelink
|
||||
$link = $this->urlGenerator->linkToRouteAbsolute(
|
||||
'files_sharing.sharecontroller.showShare',
|
||||
|
@ -409,7 +414,7 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
);
|
||||
$this->sendPasswordByMail(
|
||||
$share, MiscService::getDisplay($share->getSharedBy(), Member::TYPE_USER),
|
||||
$email, $sharesToken->getOrigPassword()
|
||||
$email, $password
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
OC::$server->getLogger()
|
||||
|
@ -579,7 +584,6 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
* @param Member $member
|
||||
* @param string $recipient
|
||||
* @param string $circleName
|
||||
* @param string $password
|
||||
*/
|
||||
public function sendMailExitingShares(
|
||||
array $unknownShares, $author, Member $member, $recipient, $circleName
|
||||
|
@ -587,11 +591,13 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
$data = [];
|
||||
|
||||
$password = '';
|
||||
if ($this->configService->enforcePasswordProtection()) {
|
||||
$password = $this->miscService->token(15);
|
||||
}
|
||||
|
||||
foreach ($unknownShares as $share) {
|
||||
try {
|
||||
$item = $this->getMailLinkFromShare($share, $member, $password);
|
||||
$password = $item['password'];
|
||||
$data[] = $item;
|
||||
$data[] = $this->getMailLinkFromShare($share, $member, $password);
|
||||
} catch (TokenDoesNotExistException $e) {
|
||||
}
|
||||
}
|
||||
|
@ -686,7 +692,6 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
* @param array $share
|
||||
* @param Member $member
|
||||
* @param string $password
|
||||
* @param string $token
|
||||
*
|
||||
* @return array
|
||||
* @throws TokenDoesNotExistException
|
||||
|
@ -704,7 +709,6 @@ class FileSharingBroadcaster implements IBroadcaster {
|
|||
return [
|
||||
'author' => $author,
|
||||
'link' => $link,
|
||||
'password' => $sharesToken->getOrigPassword(),
|
||||
'filename' => $filename
|
||||
];
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
namespace OCA\Circles\Db;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Traits\TStringTools;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
|
||||
use OCA\Circles\Exceptions\MemberDoesNotExistException;
|
||||
|
@ -37,6 +38,9 @@ use OCP\IGroup;
|
|||
class MembersRequest extends MembersRequestBuilder {
|
||||
|
||||
|
||||
use TStringTools;
|
||||
|
||||
|
||||
/**
|
||||
* Returns information about a member.
|
||||
*
|
||||
|
@ -420,10 +424,16 @@ class MembersRequest extends MembersRequestBuilder {
|
|||
* @throws MemberAlreadyExistsException
|
||||
*/
|
||||
public function createMember(Member $member) {
|
||||
|
||||
if ($member->getMemberId() === '') {
|
||||
$member->setMemberId($this->token());
|
||||
}
|
||||
|
||||
try {
|
||||
$qb = $this->getMembersInsertSql();
|
||||
$qb->setValue('circle_id', $qb->createNamedParameter($member->getCircleId()))
|
||||
->setValue('user_id', $qb->createNamedParameter($member->getUserId()))
|
||||
->setValue('member_id', $qb->createNamedParameter($member->getMemberId()))
|
||||
->setValue('user_type', $qb->createNamedParameter($member->getType()))
|
||||
->setValue('level', $qb->createNamedParameter($member->getLevel()))
|
||||
->setValue('status', $qb->createNamedParameter($member->getStatus()))
|
||||
|
|
|
@ -82,6 +82,7 @@ class MembersRequestBuilder extends CoreRequestBuilder {
|
|||
/** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||
$qb->select(
|
||||
'm.user_id', 'm.user_type', 'm.circle_id', 'm.level', 'm.status', 'm.note', 'm.contact_id',
|
||||
'member_id',
|
||||
'm.contact_meta', 'm.joined'
|
||||
)
|
||||
->from(self::TABLE_MEMBERS, 'm')
|
||||
|
@ -209,6 +210,7 @@ class MembersRequestBuilder extends CoreRequestBuilder {
|
|||
$member = new Member($data['user_id'], $data['user_type'], $data['circle_id']);
|
||||
$member->setNote($data['note']);
|
||||
$member->setContactId($data['contact_id']);
|
||||
$member->setMemberId($data['member_id']);
|
||||
|
||||
$contactMeta = json_decode($data['contact_meta'], true);
|
||||
if (is_array($contactMeta)) {
|
||||
|
|
|
@ -121,14 +121,8 @@ class TokensRequest extends TokensRequestBuilder {
|
|||
try {
|
||||
$token = $this->miscService->token(15);
|
||||
|
||||
$orig = '';
|
||||
if ($password === '' && $this->configService->enforcePasswordProtection()) {
|
||||
$password = $this->miscService->token(15);
|
||||
}
|
||||
|
||||
if ($password !== '') {
|
||||
$hasher = \OC::$server->getHasher();
|
||||
$orig = $this->origPasswordEncrypt($password);
|
||||
$password = $hasher->hash($password);
|
||||
}
|
||||
|
||||
|
@ -136,9 +130,9 @@ class TokensRequest extends TokensRequestBuilder {
|
|||
$qb->setValue('circle_id', $qb->createNamedParameter($member->getCircleId()))
|
||||
->setValue('user_id', $qb->createNamedParameter($member->getUserId()))
|
||||
->setValue('share_id', $qb->createNamedParameter($shareId))
|
||||
->setValue('member_id', $qb->createNamedParameter($member->getMemberId()))
|
||||
->setValue('token', $qb->createNamedParameter($token))
|
||||
->setValue('password', $qb->createNamedParameter($password))
|
||||
->setValue('orig_password', $qb->createNamedParameter($orig));
|
||||
->setValue('password', $qb->createNamedParameter($password));
|
||||
|
||||
$qb->execute();
|
||||
} catch (UniqueConstraintViolationException $e) {
|
||||
|
|
|
@ -81,7 +81,7 @@ class TokensRequestBuilder extends CoreRequestBuilder {
|
|||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
|
||||
/** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||
$qb->select('t.user_id', 't.circle_id', 't.share_id', 't.token', 't.orig_password')
|
||||
$qb->select('t.user_id', 't.circle_id', 't.share_id', 't.token')
|
||||
->from(self::TABLE_TOKENS, 't');
|
||||
|
||||
$this->default_select_alias = 't';
|
||||
|
@ -110,38 +110,9 @@ class TokensRequestBuilder extends CoreRequestBuilder {
|
|||
*/
|
||||
protected function parseTokensSelectSql($data) {
|
||||
$sharesToken = new SharesToken();
|
||||
|
||||
$orig = $this->get('orig_password', $data);
|
||||
$data['orig_password'] = ($orig === '') ? '' : $this->origPasswordDecrypt($orig);
|
||||
$sharesToken->import($data);
|
||||
|
||||
return $sharesToken;
|
||||
}
|
||||
|
||||
|
||||
protected function origPasswordEncrypt(string $password): string {
|
||||
$key = $this->configService->getInstanceId();
|
||||
|
||||
$ivlen = openssl_cipher_iv_length($cipher = 'AES-128-CBC');
|
||||
$iv = openssl_random_pseudo_bytes($ivlen);
|
||||
$raw = openssl_encrypt($password, $cipher, $key, $options = OPENSSL_RAW_DATA, $iv);
|
||||
$hmac = hash_hmac('sha256', $raw, $key, $as_binary = true);
|
||||
|
||||
return base64_encode($iv . $hmac . $raw);
|
||||
}
|
||||
|
||||
|
||||
protected function origPasswordDecrypt($encoded): string {
|
||||
$key = $this->configService->getInstanceId();
|
||||
$c = base64_decode($encoded);
|
||||
$ivlen = openssl_cipher_iv_length($cipher = 'AES-128-CBC');
|
||||
$iv = substr($c, 0, $ivlen);
|
||||
$hmac = substr($c, $ivlen, $sha2len = 32);
|
||||
$raw = substr($c, $ivlen + $sha2len);
|
||||
|
||||
$password = openssl_decrypt($raw, $cipher, $key, $options = OPENSSL_RAW_DATA, $iv);
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ use Closure;
|
|||
use Doctrine\DBAL\Schema\SchemaException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
|
||||
|
@ -40,6 +41,18 @@ use OCP\Migration\SimpleMigrationStep;
|
|||
*/
|
||||
class Version0017Date20191206144441 extends SimpleMigrationStep {
|
||||
|
||||
|
||||
/** @var IDBConnection */
|
||||
private $connection;
|
||||
|
||||
|
||||
/**
|
||||
* @param IDBConnection $connection
|
||||
*/
|
||||
public function __construct(IDBConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
|
@ -80,6 +93,14 @@ class Version0017Date20191206144441 extends SimpleMigrationStep {
|
|||
}
|
||||
|
||||
$table = $schema->getTable('circles_members');
|
||||
if (!$table->hasColumn('member_id')) {
|
||||
$table->addColumn(
|
||||
'member_id', Type::STRING, [
|
||||
'notnull' => false,
|
||||
'length' => 15,
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!$table->hasColumn('contact_meta')) {
|
||||
$table->addColumn(
|
||||
'contact_meta', 'string', [
|
||||
|
@ -91,9 +112,9 @@ class Version0017Date20191206144441 extends SimpleMigrationStep {
|
|||
if (!$table->hasColumn('contact_checked')) {
|
||||
$table->addColumn(
|
||||
'contact_checked', Type::SMALLINT, [
|
||||
'notnull' => false,
|
||||
'length' => 1,
|
||||
]
|
||||
'notnull' => false,
|
||||
'length' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!$table->hasColumn('contact_id')) {
|
||||
|
@ -108,20 +129,20 @@ class Version0017Date20191206144441 extends SimpleMigrationStep {
|
|||
}
|
||||
|
||||
$table = $schema->getTable('circles_tokens');
|
||||
if (!$table->hasColumn('orig_password')) {
|
||||
if (!$table->hasColumn('member_id')) {
|
||||
$table->addColumn(
|
||||
'orig_password', 'string', [
|
||||
'notnull' => false,
|
||||
'length' => 255,
|
||||
]
|
||||
'member_id', Type::STRING, [
|
||||
'notnull' => false,
|
||||
'length' => 15,
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!$table->hasColumn('accepted')) {
|
||||
$table->addColumn(
|
||||
'accepted', Type::SMALLINT, [
|
||||
'notnull' => false,
|
||||
'length' => 1,
|
||||
]
|
||||
'notnull' => false,
|
||||
'length' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -134,5 +155,66 @@ class Version0017Date20191206144441 extends SimpleMigrationStep {
|
|||
* @param array $options
|
||||
*/
|
||||
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$expr = $qb->expr();
|
||||
|
||||
$orX = $expr->orX();
|
||||
$orX->add($expr->eq('member_id', $qb->createNamedParameter('')));
|
||||
$orX->add($expr->isNull('member_id'));
|
||||
|
||||
$qb->select('circle_id', 'user_id', 'user_type')
|
||||
->from('circles_members')
|
||||
->where($orX);
|
||||
|
||||
$result = $qb->execute();
|
||||
while ($row = $result->fetch()) {
|
||||
$uniqueId = substr(bin2hex(openssl_random_pseudo_bytes(24)), 0, 15);
|
||||
|
||||
$update = $this->connection->getQueryBuilder();
|
||||
$expru = $update->expr();
|
||||
$update->update('circles_members')
|
||||
->set('member_id', $update->createNamedParameter($uniqueId))
|
||||
->where($expru->eq('circle_id', $update->createNamedParameter($row['circle_id'])))
|
||||
->andWhere($expru->eq('user_id', $update->createNamedParameter($row['user_id'])))
|
||||
->andWhere($expru->eq('user_type', $update->createNamedParameter($row['user_type'])));
|
||||
|
||||
$update->execute();
|
||||
}
|
||||
|
||||
|
||||
$qb2 = $this->connection->getQueryBuilder();
|
||||
$expr2 = $qb2->expr();
|
||||
$orX = $expr2->orX();
|
||||
$orX->add($expr2->eq('member_id', $qb2->createNamedParameter('')));
|
||||
$orX->add($expr2->isNull('member_id'));
|
||||
$qb2->select('user_id', 'circle_id')
|
||||
->from('circles_tokens')
|
||||
->where($orX);
|
||||
|
||||
$result = $qb2->execute();
|
||||
while ($row = $result->fetch()) {
|
||||
$qbm = $this->connection->getQueryBuilder();
|
||||
$exprm = $qbm->expr();
|
||||
|
||||
$qbm->select('member_id')
|
||||
->from('circles_members')
|
||||
->where($exprm->eq('circle_id', $qbm->createNamedParameter($row['circle_id'])))
|
||||
->andWhere($exprm->eq('user_id', $qbm->createNamedParameter($row['user_id'])))
|
||||
->andWhere($exprm->neq('user_type', $qbm->createNamedParameter('1')));
|
||||
|
||||
$resultm = $qbm->execute();
|
||||
$member = $resultm->fetch();
|
||||
|
||||
$update = $this->connection->getQueryBuilder();
|
||||
$expru = $update->expr();
|
||||
$update->update('circles_tokens')
|
||||
->set('member_id', $update->createNamedParameter($member['member_id']))
|
||||
->where($expru->eq('circle_id', $update->createNamedParameter($row['circle_id'])))
|
||||
->andWhere($expru->eq('user_id', $update->createNamedParameter($row['user_id'])));
|
||||
|
||||
$update->execute();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ class BaseMember implements \JsonSerializable {
|
|||
/** @var string */
|
||||
private $userId = '';
|
||||
|
||||
/** @var string */
|
||||
private $memberId = '';
|
||||
|
||||
/** @var int */
|
||||
private $type = self::TYPE_USER;
|
||||
|
||||
|
@ -181,6 +184,18 @@ class BaseMember implements \JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public function setMemberId($memberId) {
|
||||
$this->memberId = $memberId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMemberId() {
|
||||
return $this->memberId;
|
||||
}
|
||||
|
||||
|
||||
public function setDisplayName($display) {
|
||||
$this->displayName = $display;
|
||||
|
||||
|
|
|
@ -54,9 +54,6 @@ class SharesToken implements JsonSerializable {
|
|||
/** @var string */
|
||||
private $token = '';
|
||||
|
||||
/** @var string */
|
||||
private $origPassword = '';
|
||||
|
||||
|
||||
/**
|
||||
* SharesToken constructor.
|
||||
|
@ -141,25 +138,6 @@ class SharesToken implements JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOrigPassword(): string {
|
||||
return $this->origPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $origPassword
|
||||
*
|
||||
* @return SharesToken
|
||||
*/
|
||||
public function setOrigPassword(string $origPassword): self {
|
||||
$this->origPassword = $origPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
|
@ -168,7 +146,6 @@ class SharesToken implements JsonSerializable {
|
|||
$this->setUserId($this->get('user_id', $data, ''));
|
||||
$this->setShareId($this->get('share_id', $data, ''));
|
||||
$this->setToken($this->get('token', $data, ''));
|
||||
$this->setOrigPassword($this->get('orig_password', $data, ''));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue