| @@ -37,8 +37,9 @@ impl Database { · 36 unmodified lines |
| 37 | } | 37 | } |
| 38 | | 38 | |
| 39 | let channel = channel::ActiveModel { | 39 | let channel = channel::ActiveModel { |
| | 40 | id: ActiveValue::NotSet, |
| 40 | name: ActiveValue::Set(name.to_string()), | 41 | name: ActiveValue::Set(name.to_string()), |
| 41 | ..Default::default() | 42 | visibility: ActiveValue::Set(ChannelVisibility::ChannelMembers), |
| 42 | } | 43 | } |
| 43 | .insert(&*tx) | 44 | .insert(&*tx) |
| 44 | .await?; | 45 | .await?; |
| @@ -89,6 +90,29 @@ impl Database { · 44 unmodified lines |
| 89 | .await | 90 | .await |
| 90 | } | 91 | } |
| 91 | | 92 | |
| | 93 | pub async fn set_channel_visibility( |
| | 94 | &self, |
| | 95 | channel_id: ChannelId, |
| | 96 | visibility: ChannelVisibility, |
| | 97 | user_id: UserId, |
| | 98 | ) -> Result<()> { |
| | 99 | self.transaction(move |tx| async move { |
| | 100 | self.check_user_is_channel_admin(channel_id, user_id, &*tx) |
| | 101 | .await?; |
| | 102 | |
| | 103 | channel::ActiveModel { |
| | 104 | id: ActiveValue::Unchanged(channel_id), |
| | 105 | visibility: ActiveValue::Set(visibility), |
| | 106 | ..Default::default() |
| | 107 | } |
| | 108 | .update(&*tx) |
| | 109 | .await?; |
| | 110 | |
| | 111 | Ok(()) |
| | 112 | }) |
| | 113 | .await |
| | 114 | } |
| | 115 | |
| 92 | pub async fn delete_channel( | 116 | pub async fn delete_channel( |
| 93 | &self, | 117 | &self, |
| 94 | channel_id: ChannelId, | 118 | channel_id: ChannelId, |
| @@ -160,11 +184,11 @@ impl Database { · 65 unmodified lines |
| 160 | &self, | 184 | &self, |
| 161 | channel_id: ChannelId, | 185 | channel_id: ChannelId, |
| 162 | invitee_id: UserId, | 186 | invitee_id: UserId, |
| 163 | inviter_id: UserId, | 187 | admin_id: UserId, |
| 164 | role: ChannelRole, | 188 | role: ChannelRole, |
| 165 | ) -> Result<()> { | 189 | ) -> Result<()> { |
| 166 | self.transaction(move |tx| async move { | 190 | self.transaction(move |tx| async move { |
| 167 | self.check_user_is_channel_admin(channel_id, inviter_id, &*tx) | 191 | self.check_user_is_channel_admin(channel_id, admin_id, &*tx) |
| 168 | .await?; | 192 | .await?; |
| 169 | | 193 | |
| 170 | channel_member::ActiveModel { | 194 | channel_member::ActiveModel { |
| @@ -262,10 +286,10 @@ impl Database { · 91 unmodified lines |
| 262 | &self, | 286 | &self, |
| 263 | channel_id: ChannelId, | 287 | channel_id: ChannelId, |
| 264 | member_id: UserId, | 288 | member_id: UserId, |
| 265 | remover_id: UserId, | 289 | admin_id: UserId, |
| 266 | ) -> Result<()> { | 290 | ) -> Result<()> { |
| 267 | self.transaction(|tx| async move { | 291 | self.transaction(|tx| async move { |
| 268 | self.check_user_is_channel_admin(channel_id, remover_id, &*tx) | 292 | self.check_user_is_channel_admin(channel_id, admin_id, &*tx) |
| 269 | .await?; | 293 | .await?; |
| 270 | | 294 | |
| 271 | let result = channel_member::Entity::delete_many() | 295 | let result = channel_member::Entity::delete_many() |
| @@ -481,12 +505,12 @@ impl Database { · 209 unmodified lines |
| 481 | pub async fn set_channel_member_role( | 505 | pub async fn set_channel_member_role( |
| 482 | &self, | 506 | &self, |
| 483 | channel_id: ChannelId, | 507 | channel_id: ChannelId, |
| 484 | from: UserId, | 508 | admin_id: UserId, |
| 485 | for_user: UserId, | 509 | for_user: UserId, |
| 486 | role: ChannelRole, | 510 | role: ChannelRole, |
| 487 | ) -> Result<()> { | 511 | ) -> Result<()> { |
| 488 | self.transaction(|tx| async move { | 512 | self.transaction(|tx| async move { |
| 489 | self.check_user_is_channel_admin(channel_id, from, &*tx) | 513 | self.check_user_is_channel_admin(channel_id, admin_id, &*tx) |
| 490 | .await?; | 514 | .await?; |
| 491 | | 515 | |
| 492 | let result = channel_member::Entity::update_many() | 516 | let result = channel_member::Entity::update_many() |
| @@ -613,43 +637,147 @@ impl Database { · 120 unmodified lines |
| 613 | Ok(user_ids) | 637 | Ok(user_ids) |
| 614 | } | 638 | } |
| 615 | | 639 | |
| | 640 | pub async fn check_user_is_channel_admin( |
| | 641 | &self, |
| | 642 | channel_id: ChannelId, |
| | 643 | user_id: UserId, |
| | 644 | tx: &DatabaseTransaction, |
| | 645 | ) -> Result<()> { |
| | 646 | match self.channel_role_for_user(channel_id, user_id, tx).await? { |
| | 647 | Some(ChannelRole::Admin) => Ok(()), |
| | 648 | Some(ChannelRole::Member) |
| | 649 | | Some(ChannelRole::Banned) |
| | 650 | | Some(ChannelRole::Guest) |
| | 651 | | None => Err(anyhow!( |
| | 652 | "user is not a channel admin or channel does not exist" |
| | 653 | ))?, |
| | 654 | } |
| | 655 | } |
| | 656 | |
| 616 | pub async fn check_user_is_channel_member( | 657 | pub async fn check_user_is_channel_member( |
| 617 | &self, | 658 | &self, |
| 618 | channel_id: ChannelId, | 659 | channel_id: ChannelId, |
| 619 | user_id: UserId, | 660 | user_id: UserId, |
| 620 | tx: &DatabaseTransaction, | 661 | tx: &DatabaseTransaction, |
| 621 | ) -> Result<()> { | 662 | ) -> Result<()> { |
| 622 | let channel_ids = self.get_channel_ancestors(channel_id, tx).await?; | 663 | match self.channel_role_for_user(channel_id, user_id, tx).await? { |
| 623 | channel_member::Entity::find() | 664 | Some(ChannelRole::Admin) | Some(ChannelRole::Member) => Ok(()), |
| 624 | .filter( | 665 | Some(ChannelRole::Banned) | Some(ChannelRole::Guest) | None => Err(anyhow!( |
| 625 | channel_member::Column::ChannelId | 666 | "user is not a channel member or channel does not exist" |
| 626 | .is_in(channel_ids) | 667 | ))?, |
| 627 | .and(channel_member::Column::UserId.eq(user_id)), | 668 | } |
| 628 | ) | | |
| 629 | .one(&*tx) | | |
| 630 | .await? | | |
| 631 | .ok_or_else(|| anyhow!("user is not a channel member or channel does not exist"))?; | | |
| 632 | Ok(()) | | |
| 633 | } | 669 | } |
| 634 | | 670 | |
| 635 | pub async fn check_user_is_channel_admin( | 671 | pub async fn check_user_is_channel_participant( |
| 636 | &self, | 672 | &self, |
| 637 | channel_id: ChannelId, | 673 | channel_id: ChannelId, |
| 638 | user_id: UserId, | 674 | user_id: UserId, |
| 639 | tx: &DatabaseTransaction, | 675 | tx: &DatabaseTransaction, |
| 640 | ) -> Result<()> { | 676 | ) -> Result<()> { |
| | 677 | match self.channel_role_for_user(channel_id, user_id, tx).await? { |
| | 678 | Some(ChannelRole::Admin) | Some(ChannelRole::Member) | Some(ChannelRole::Guest) => { |
| | 679 | Ok(()) |
| | 680 | } |
| | 681 | Some(ChannelRole::Banned) | None => Err(anyhow!( |
| | 682 | "user is not a channel participant or channel does not exist" |
| | 683 | ))?, |
| | 684 | } |
| | 685 | } |
| | 686 | |
| | 687 | pub async fn channel_role_for_user( |
| | 688 | &self, |
| | 689 | channel_id: ChannelId, |
| | 690 | user_id: UserId, |
| | 691 | tx: &DatabaseTransaction, |
| | 692 | ) -> Result<Option<ChannelRole>> { |
| 641 | let channel_ids = self.get_channel_ancestors(channel_id, tx).await?; | 693 | let channel_ids = self.get_channel_ancestors(channel_id, tx).await?; |
| 642 | channel_member::Entity::find() | 694 | |
| | 695 | #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] |
| | 696 | enum QueryChannelMembership { |
| | 697 | ChannelId, |
| | 698 | Role, |
| | 699 | Admin, |
| | 700 | Visibility, |
| | 701 | } |
| | 702 | |
| | 703 | let mut rows = channel_member::Entity::find() |
| | 704 | .left_join(channel::Entity) |
| 643 | .filter( | 705 | .filter( |
| 644 | channel_member::Column::ChannelId | 706 | channel_member::Column::ChannelId |
| 645 | .is_in(channel_ids) | 707 | .is_in(channel_ids) |
| 646 | .and(channel_member::Column::UserId.eq(user_id)) | 708 | .and(channel_member::Column::UserId.eq(user_id)), |
| 647 | .and(channel_member::Column::Admin.eq(true)), | | |
| 648 | ) | 709 | ) |
| 649 | .one(&*tx) | 710 | .select_only() |
| 650 | .await? | 711 | .column(channel_member::Column::ChannelId) |
| 651 | .ok_or_else(|| anyhow!("user is not a channel admin or channel does not exist"))?; | 712 | .column(channel_member::Column::Role) |
| 652 | Ok(()) | 713 | .column(channel_member::Column::Admin) |
| | 714 | .column(channel::Column::Visibility) |
| | 715 | .into_values::<_, QueryChannelMembership>() |
| | 716 | .stream(&*tx) |
| | 717 | .await?; |
| | 718 | |
| | 719 | let mut is_admin = false; |
| | 720 | let mut is_member = false; |
| | 721 | let mut is_participant = false; |
| | 722 | let mut is_banned = false; |
| | 723 | let mut current_channel_visibility = None; |
| | 724 | |
| | 725 | // note these channels are not iterated in any particular order, |
| | 726 | // our current logic takes the highest permission available. |
| | 727 | while let Some(row) = rows.next().await { |
| | 728 | let (ch_id, role, admin, visibility): ( |
| | 729 | ChannelId, |
| | 730 | Option<ChannelRole>, |
| | 731 | bool, |
| | 732 | ChannelVisibility, |
| | 733 | ) = row?; |
| | 734 | match role { |
| | 735 | Some(ChannelRole::Admin) => is_admin = true, |
| | 736 | Some(ChannelRole::Member) => is_member = true, |
| | 737 | Some(ChannelRole::Guest) => { |
| | 738 | if visibility == ChannelVisibility::Public { |
| | 739 | is_participant = true |
| | 740 | } |
| | 741 | } |
| | 742 | Some(ChannelRole::Banned) => is_banned = true, |
| | 743 | None => { |
| | 744 | // rows created from pre-role collab server. |
| | 745 | if admin { |
| | 746 | is_admin = true |
| | 747 | } else { |
| | 748 | is_member = true |
| | 749 | } |
| | 750 | } |
| | 751 | } |
| | 752 | if channel_id == ch_id { |
| | 753 | current_channel_visibility = Some(visibility); |
| | 754 | } |
| | 755 | } |
| | 756 | // free up database connection |
| | 757 | drop(rows); |
| | 758 | |
| | 759 | Ok(if is_admin { |
| | 760 | Some(ChannelRole::Admin) |
| | 761 | } else if is_member { |
| | 762 | Some(ChannelRole::Member) |
| | 763 | } else if is_banned { |
| | 764 | Some(ChannelRole::Banned) |
| | 765 | } else if is_participant { |
| | 766 | if current_channel_visibility.is_none() { |
| | 767 | current_channel_visibility = channel::Entity::find() |
| | 768 | .filter(channel::Column::Id.eq(channel_id)) |
| | 769 | .one(&*tx) |
| | 770 | .await? |
| | 771 | .map(|channel| channel.visibility); |
| | 772 | } |
| | 773 | if current_channel_visibility == Some(ChannelVisibility::Public) { |
| | 774 | Some(ChannelRole::Guest) |
| | 775 | } else { |
| | 776 | None |
| | 777 | } |
| | 778 | } else { |
| | 779 | None |
| | 780 | }) |
| 653 | } | 781 | } |
| 654 | | 782 | |
| 655 | /// Returns the channel ancestors, deepest first | 783 | /// Returns the channel ancestors, deepest first |