Skip to content

Commit

Permalink
Enable audit by configuration nextcloud#163
Browse files Browse the repository at this point in the history
- audit of following actions:
- user X created circle Z;
- user X removed circle Z;
- user X change name of circle Z for circle W;
- user X was added to circle U by user Z;
- user X shared file/folder with circle Y;
- user X, that created circle, unshared file/folder with circle Y
- member X accepted invitation to circle Y by user Z;
- member X left circle Y;
- user X change role of member Y in circle Z for W.
- user X was invited to circle U by user Z

- configuration by circles_enable_audit in config.php

Signed-off-by: Flávio Gomes da Silva Lisboa <flavio.lisboa@serpro.gov.br>
  • Loading branch information
Flávio Gomes da Silva Lisboa committed Jul 27, 2018
1 parent b345546 commit cc594d2
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 23 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,36 @@ Anyone can find the circle and request an invitation; but only members will see
- A **Secret Circle** is an hidden group that can only be seen by its members or by people knowing the exact name of the circle.
Non-members won't be able to find your secret circle using the search bar.

## Settings

Circles settings is available in Nextcloud interface in **Settings / Additional Settings**.

### Async Testing

This option allows to initiate an async test in Circles.

### Allow linking of groups

This option allows that groups be linked to circles.

### Allow federated circles

This option allows that circles from different Nextclouds can be linked together.

### Enable audit

This options allows that actions of circles, members and sharing can be audit with records into log. Following actions are audited:

* User X created circle Z;
* User X removed circle Z;
* User X change name of circle Z for circle W;
* User X was added to circle U by user Z;
* User X shared file/folder with circle Y;
* User X, that created circle, unshared file/folder with circle Y
* Member X accepted invitation to circle Y by user Z;
* Member X left circle Y;
* User X change role of member Y in circle Z for W.
* User X was invited to circle U by user Z

***
# API (PHP & Javascript)
Expand Down
36 changes: 22 additions & 14 deletions lib/Model/BaseMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,20 +277,7 @@ public function jsonSerialize() {
}

public function getLevelString() {
switch ($this->getLevel()) {
case self::LEVEL_NONE:
return 'Not a member';
case self::LEVEL_MEMBER:
return 'Member';
case self::LEVEL_MODERATOR:
return 'Moderator';
case self::LEVEL_ADMIN:
return 'Admin';
case self::LEVEL_OWNER:
return 'Owner';
}

return 'none';
return self::getLevelStringFromCode($this->getLevel());
}


Expand All @@ -308,4 +295,25 @@ public function getTypeString() {

return 'none';
}

/**
* @param integer $code
* @return string
*/
public static function getLevelStringFromCode($code) {
switch ($code) {
case self::LEVEL_NONE:
return 'Not a member';
case self::LEVEL_MEMBER:
return 'Member';
case self::LEVEL_MODERATOR:
return 'Moderator';
case self::LEVEL_ADMIN:
return 'Admin';
case self::LEVEL_OWNER:
return 'Owner';
}

return 'none';
}
}
47 changes: 47 additions & 0 deletions lib/Service/BaseService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
*
* @copyright 2018
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCA\Circles\Service;

use OCA\Circles\AppInfo\Application;
use OC\User\User;

abstract class BaseService {
protected static $user = null;

/**
* @return User
*/
protected function getUser()
{
if (self::$user == null){
$app = new Application();
self::$user = $app->getContainer()->query('UserSession')->getUser();
}
return self::$user;
}
}
41 changes: 40 additions & 1 deletion lib/Service/CirclesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Member;
use OCP\IL10N;
use OCP\Util;

class CirclesService {
class CirclesService extends BaseService {

/** @var string */
private $userId;
Expand Down Expand Up @@ -150,6 +151,9 @@ public function createCircle($type, $name) {
try {
$this->circlesRequest->createCircle($circle, $this->userId);
$this->membersRequest->createMember($circle->getOwner());

$owner = $circle->getOwner()->getDisplayName();
$this->miscService->log("user $owner created circle $name");
} catch (CircleAlreadyExistsException $e) {
throw $e;
}
Expand Down Expand Up @@ -290,17 +294,25 @@ public function settingsCircle($circleUniqueId, $settings) {

try {
$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
$formerCircleName = $circle->getName();
$circle->getHigherViewer()
->hasToBeOwner();

$ak = array_keys($settings);
$changes = '';
foreach ($ak AS $k) {
if (trim($circle->getSetting($k)) !== trim($settings[$k])){
$changes .= ((empty($changes) ? '' : ' and ') . "$k to {$settings[$k]}");
}
$circle->setSetting($k, $settings[$k]);
}

$this->circlesRequest->updateCircle($circle, $this->userId);

$this->eventsService->onSettingsChange($circle);

$user = $this->getUser()->getDisplayName();
$this->miscService->log("user $user updated circle $formerCircleName changing $changes");
} catch (\Exception $e) {
throw $e;
}
Expand All @@ -325,11 +337,23 @@ public function joinCircle($circleUniqueId) {
$member = $this->membersRequest->getFreshNewMember(
$circleUniqueId, $this->userId, Member::TYPE_USER
);
$formerStatus = $member->getStatus();
$member->hasToBeAbleToJoinTheCircle();
$member->joinCircle($circle->getType());
$this->membersRequest->updateMember($member);

$this->eventsService->onMemberNew($circle, $member);

$circleName = $circle->getName();
$circleType = $circle->getType();
$memberName = $member->getDisplayName();
if ($formerStatus == Member::STATUS_INVITED){
$this->miscService->log("member $memberName accepted invitation to circle $circleName");
} else if ($circle->getType() == Circle::CIRCLES_CLOSED) {
$this->miscService->log("member $memberName requested to join circle $circleName");
} else {
$this->miscService->log("member $memberName joined circle $circleName");
}
} catch (\Exception $e) {
throw $e;
}
Expand All @@ -354,11 +378,23 @@ public function leaveCircle($circleUniqueId) {
$member->hasToBeMemberOrAlmost();
$member->cantBeOwner();

$circleName = $circle->getName();
$formerStatus = $member->getStatus();
$memberName = $member->getDisplayName();

$this->eventsService->onMemberLeaving($circle, $member);

$this->membersRequest->removeMember($member);
$this->sharesRequest->removeSharesFromMember($member);

if ($formerStatus == Member::STATUS_INVITED){
$this->miscService->log("member $memberName refused invitation to circle $circleName");
} else if ($circle->getType() == Circle::CIRCLES_CLOSED) {
$this->miscService->log("member $memberName cancelled invitation from circle $circleName");
} else {
$this->miscService->log("member $memberName left circle $circleName");
}

return $member;
}

Expand All @@ -382,6 +418,9 @@ public function removeCircle($circleUniqueId) {
$this->membersRequest->removeAllFromCircle($circleUniqueId);
$this->circlesRequest->destroyCircle($circleUniqueId);

$circleName = $circle->getName();
$user = $this->getUser()->getDisplayName();
$this->miscService->log("user $user destroyed circle $circleName");
}


Expand Down
22 changes: 19 additions & 3 deletions lib/Service/MembersService.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@
use OCA\Circles\Model\Member;
use OCP\IL10N;
use OCP\IUserManager;
use OCP\Util;

class MembersService {
class MembersService extends BaseService {

/** @var string */
private $userId;
Expand Down Expand Up @@ -118,10 +119,15 @@ public function addMember($circleUniqueId, $ident, $type) {
$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
$circle->getHigherViewer()
->hasToBeModerator();

if (!$this->addMassiveMembers($circle, $ident, $type)) {
$this->addSingleMember($circle, $ident, $type);
}

$action = ($type == Circle::CIRCLES_CLOSED ? 'invited' : 'added');
$circleName = $circle->getName();
$user = $this->getUser()->getDisplayName();
$this->miscService->log("user $user $action member $ident to circle $circleName");
} catch (\Exception $e) {
throw $e;
}
Expand Down Expand Up @@ -402,7 +408,12 @@ public function levelMember($circleUniqueId, $name, $type, $level) {
$member = $this->membersRequest->forceGetMember($circle->getUniqueId(), $name, $type);
$member->levelHasToBeEditable();
$this->updateMemberLevel($circle, $member, $level);


$circleName = $circle->getName();
$levelString = Member::getLevelStringFromCode($level);
$memberName = $member->getDisplayName();
$user = $this->getUser()->getDisplayName();
$this->miscService->log("$user changed level of $memberName from circle $circleName to $levelString");
return $this->membersRequest->getMembers(
$circle->getUniqueId(), $circle->getHigherViewer()
);
Expand Down Expand Up @@ -507,6 +518,11 @@ public function removeMember($circleUniqueId, $name, $type) {

$circle->getHigherViewer()
->hasToBeHigherLevel($member->getLevel());

$user = $this->getUser()->getDisplayName();
$memberName = $member->getDisplayName();
$circleName = $circle->getName();
$this->miscService->log("user $user removed member $memberName from circle $circleName");
} catch (\Exception $e) {
throw $e;
}
Expand Down
Loading

0 comments on commit cc594d2

Please sign in to comment.