🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-10-13 0:26:31.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-10-13 0:26:31.0 +01:00:00
commit
864c1d46af66125b7e91f3fb01d77c8b261dbadf [patch]
tree
2c320ba435b544a69720e4986a815247767df671
parent
a33dd8ea4065881a8828510a21c670156f9acf20
download
864c1d46af66125b7e91f3fb01d77c8b261dbadf.tar.gz

Allow organisations to be marked as public, granting VISIBLE to everyone

Fixes #25

Diff

 chartered-db/src/crates.rs                                     |  5 +++++
 chartered-db/src/organisations.rs                              | 35 +++++++++++++++++++++++++----------
 chartered-db/src/schema.rs                                     |  1 +
 migrations/2021-08-31-214501_create_crates_table/up.sql        |  3 ++-
 chartered-web/src/endpoints/web_api/crates/mod.rs              |  2 +-
 chartered-web/src/endpoints/web_api/crates/recently_created.rs |  2 +-
 6 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/chartered-db/src/crates.rs b/chartered-db/src/crates.rs
index 21f4dfc..76767f0 100644
--- a/chartered-db/src/crates.rs
+++ a/chartered-db/src/crates.rs
@@ -90,6 +90,11 @@
            crate::schema::user_organisation_permissions::permissions.nullable(),
            0,
        ))
        .bitwise_or(diesel::dsl::sql::<diesel::sql_types::Integer>(&format!(
            "(CASE WHEN {} THEN {} OR 0 END)",
            "organisations.public",
            UserPermission::VISIBLE.bits(),
        )))
    };
}

diff --git a/chartered-db/src/organisations.rs b/chartered-db/src/organisations.rs
index 259fdc2..964f9ab 100644
--- a/chartered-db/src/organisations.rs
+++ a/chartered-db/src/organisations.rs
@@ -1,5 +1,6 @@
use crate::{
    crates::Crate, permissions::UserPermission, users::User, BitwiseExpressionMethods, Error,
    coalesce, crates::Crate, permissions::UserPermission, users::User, BitwiseExpressionMethods,
    Error,
};

use super::{
@@ -12,23 +13,36 @@

use std::sync::Arc;

macro_rules! select_permissions {
    () => {
        coalesce(
            crate::schema::user_organisation_permissions::permissions.nullable(),
            0,
        )
        .bitwise_or(diesel::dsl::sql::<diesel::sql_types::Integer>(&format!(
            "COALESCE(CASE WHEN {} THEN {} OR 0 END, 0)",
            "public",
            UserPermission::VISIBLE.bits(),
        )))
    };
}

#[derive(Identifiable, Queryable, Associations, PartialEq, Eq, Hash, Debug)]
pub struct Organisation {
    pub id: i32,
    pub uuid: SqlUuid,
    pub name: String,
    pub description: String,
    pub public: bool,
}

impl Organisation {
    pub async fn list(conn: ConnectionPool, requesting_user_id: i32) -> Result<Vec<Organisation>> {
        use user_organisation_permissions::dsl::permissions;

        tokio::task::spawn_blocking(move || {
            let conn = conn.get()?;

            organisations::table
                .inner_join(
                .left_join(
                    user_organisation_permissions::table.on(user_organisation_permissions::user_id
                        .eq(requesting_user_id)
                        .and(
@@ -37,7 +51,7 @@
                        )),
                )
                .filter(
                    permissions
                    select_permissions!()
                        .bitwise_and(UserPermission::VISIBLE.bits())
                        .eq(UserPermission::VISIBLE.bits()),
                )
@@ -68,17 +82,10 @@
                        )),
                )
                .filter(organisation_name.eq(given_name))
                .select((
                    user_organisation_permissions::dsl::permissions.nullable(),
                    organisations::all_columns,
                ))
                .get_result::<(Option<UserPermission>, _)>(&conn)
                .select((select_permissions!(), organisations::all_columns))
                .get_result(&conn)
                .optional()?
                .ok_or(Error::MissingOrganisation)?;

            let permissions = permissions.ok_or(Error::MissingOrganisationPermission(
                UserPermission::VISIBLE,
            ))?;

            Ok(OrganisationWithPermissions {
                organisation,
diff --git a/chartered-db/src/schema.rs b/chartered-db/src/schema.rs
index 10e3e9e..cebf439 100644
--- a/chartered-db/src/schema.rs
+++ a/chartered-db/src/schema.rs
@@ -36,6 +36,7 @@
        uuid -> Binary,
        name -> Text,
        description -> Text,
        public -> Bool,
    }
}

diff --git a/migrations/2021-08-31-214501_create_crates_table/up.sql b/migrations/2021-08-31-214501_create_crates_table/up.sql
index ff02770..ffa58e9 100644
--- a/migrations/2021-08-31-214501_create_crates_table/up.sql
+++ a/migrations/2021-08-31-214501_create_crates_table/up.sql
@@ -16,7 +16,8 @@
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    uuid BINARY(128) NOT NULL UNIQUE,
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT NOT NULL DEFAULT ""
    description TEXT NOT NULL DEFAULT "",
    public BOOLEAN NOT NULL DEFAULT FALSE
);

INSERT INTO organisations (id, uuid, name, description) VALUES (1, X'936DA01F9ABD4D9D80C702AF85C822A8', "core", "My first organisation");
diff --git a/chartered-web/src/endpoints/web_api/crates/mod.rs b/chartered-web/src/endpoints/web_api/crates/mod.rs
index cb526c2..da1a711 100644
--- a/chartered-web/src/endpoints/web_api/crates/mod.rs
+++ a/chartered-web/src/endpoints/web_api/crates/mod.rs
@@ -1,9 +1,9 @@
mod info;
mod members;
mod most_downloaded;
mod recently_created;
mod recently_updated;
mod search;
mod recently_created;

use axum::{
    body::{Body, BoxBody},
diff --git a/chartered-web/src/endpoints/web_api/crates/recently_created.rs b/chartered-web/src/endpoints/web_api/crates/recently_created.rs
index cff1345..45942e9 100644
--- a/chartered-web/src/endpoints/web_api/crates/recently_created.rs
+++ a/chartered-web/src/endpoints/web_api/crates/recently_created.rs
@@ -1,8 +1,8 @@
use axum::{extract, Json};
use chartered_db::{crates::Crate, users::User, ConnectionPool};
use chrono::{DateTime, TimeZone, Utc};
use serde::Serialize;
use std::sync::Arc;
use chrono::{DateTime, TimeZone, Utc};
use thiserror::Error;

#[derive(Error, Debug)]