Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

[V2.0] Track Permissions Through Topics #270

Merged

Conversation

DyrellC
Copy link
Contributor

@DyrellC DyrellC commented Jul 12, 2022

Description of change

Currently the only place we use Permissioned is when we are doing checks on Keyload messages, but those permissions are not retained in store anywhere, as our cursor store only uses the Identifier. To allow for that permission retention we need to change CursorStore to map by Permissioned<Identifier> instead of just Identifier. This brings a host of other trickling changes along with it.

For example, a User will be able to check their permissions on a topic before they attempt to send messages, failing if they are registered as Read by a topic administrator. Additionally administrative privileges can be properly assigned and forwarded through the topics.

Requires #262 to be merged

Type of change

  • Enhancement (a non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

How the change has been tested

New section added to end of examples to have Author re-subscribe SubscriberA and grant them Admin privileges, confirming that they carry forward into new branches.

  • All previous examples complete
  • All previous tests complete

Copy link
Contributor

@kwek20 kwek20 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my end, the tangle test fails at did.rs:143


impl Mask<&Permissioned<&Identifier>> for sizeof::Context {
fn mask(&mut self, permission: &Permissioned<&Identifier>) -> Result<&mut Self> {
self.mask(&permission.take())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to avoid the take here and 245, move the impl from their respective methods to this one, and use self.mask(&permission.as_ref()) to call this from the other method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that does make more sense, changed

.is_cursor_tracked(topic, subscriber.identifier());
!subscriber.is_readonly() && no_tracked_cursor
let permission = self.state.cursor_store.get_permission(topic, subscriber.identifier());
let tracked_and_equal = permission.is_some() && permission == Some(&subscriber.take());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could replace the permission == Some() with !(permission.unwrap().as_ref() == subscriber)


// If a branch admin does not include a user in the keyload, any further messages sent by
// the user will not be received by the others, so remove them from the publisher pool
let stored_subscribers: Vec<(Topic, Permissioned<Identifier>, usize)> = self
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cant we use cursors_by_topic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can and should yes

{
self.state
.cursor_store
.insert_cursor(&topic, Permissioned::Read(perm.identifier().clone()), cursor);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm we store the subscriber in the list if he wasnt added anymore, are we sure we want this behaviour?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's either this or removing them, which would reset their cursor standing, so I think it's appropriate to retain the cursor but in a state that it won't be used to iterate new messages unless added again in a later keyload by the Author.

Copy link
Contributor

@kwek20 kwek20 Aug 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, if youre not included in the keyload yoou shouldnt have access to the data.
I know we said that keyloads carry on through branches, but i wasnt thinking on a additive manner, same keyload or new keyload only. Lets see what @arnauorriols thinks about this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which would reset their cursor standing

Oh! I also thought it was weird not to remove the cursor, but you are right, we need to keep the cursor around in case the user is added to the branch again.

To me, if youre not included in the keyload yoou shouldnt have access to the data

This does not change. the user that is not included in the keyload cannot decode the message, period. The fact that it remains tracked is to keep the cursor around. It would probably be less confusing if instead of using the permissions, we had a type that expressed this intent explicitly

}

impl Permissioned<&Identifier> {
pub fn take(self) -> Permissioned<Identifier> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also its not much of a take(), more a clone. could be changed to take an &self and then (*id).clone(). Why not call it clone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was grappling between the two honestly so no problem changing that to clone

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I remember now why I chose take, if it's not an actual clone implementation clippy does not like it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets implement a From trait instead then, i think it looks better.

impl From<Permissioned<&Identifier>> for Permissioned<Identifier> {
    fn from(permisison: Permissioned<&Identifier>) -> Self {
        match permisison {
            Permissioned::Read(id) => Permissioned::Read(id.clone()),
            Permissioned::ReadWrite(id, duration) => Permissioned::ReadWrite(id.clone(), duration),
            Permissioned::Admin(id) => Permissioned::Admin(id.clone()),
        }
    }
}

.subscribers()
.map(|s| {
if s == permission.identifier() {
Permissioned::Admin(s.clone())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this step for? Just for admin to be able to check his permissions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For admin to establish that they will continue to be admin going forward and not replace their permissions with a read/write

Copy link
Contributor

@arnauorriols arnauorriols left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my end, we can merge this

{
self.state
.cursor_store
.insert_cursor(&topic, Permissioned::Read(perm.identifier().clone()), cursor);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which would reset their cursor standing

Oh! I also thought it was weird not to remove the cursor, but you are right, we need to keep the cursor around in case the user is added to the branch again.

To me, if youre not included in the keyload yoou shouldnt have access to the data

This does not change. the user that is not included in the keyload cannot decode the message, period. The fact that it remains tracked is to keep the cursor around. It would probably be less confusing if instead of using the permissions, we had a type that expressed this intent explicitly

@kwek20 kwek20 requested review from arnauorriols and kwek20 August 22, 2022 16:32
Copy link
Contributor

@kwek20 kwek20 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@DyrellC DyrellC merged commit bd72932 into iotaledger:v2.0-dev Aug 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants