feat: add session service, version bump

This commit is contained in:
əlemi 2024-08-21 21:38:36 +02:00
parent ddd4552e09
commit f2863537c8
Signed by: alemi
GPG key ID: A4895B84D311642C
7 changed files with 70 additions and 32 deletions

View file

@ -1,15 +1,15 @@
[package] [package]
name = "codemp-proto" name = "codemp-proto"
version = "0.6.0" version = "0.6.1"
edition = "2021" edition = "2021"
[lib] [lib]
name = "codemp_proto" name = "codemp_proto"
[dependencies] [dependencies]
prost = "0.12.3" prost = "0.13"
tonic = "0.11.0" tonic = "0.12"
uuid = "1.7.0" uuid = "1.7"
[build-dependencies] [build-dependencies]
tonic-build = "0.11.0" tonic-build = "0.12"

View file

@ -5,6 +5,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
"proto/cursor.proto", "proto/cursor.proto",
"proto/files.proto", "proto/files.proto",
"proto/auth.proto", "proto/auth.proto",
"proto/session.proto",
"proto/workspace.proto", "proto/workspace.proto",
"proto/buffer.proto", "proto/buffer.proto",
], ],

View file

@ -2,19 +2,18 @@ syntax = "proto2";
package auth; package auth;
// authenticates users, issuing tokens import "common.proto";
// service entrypoint, authenticate users and grant initial token
service Auth { service Auth {
// send credentials and join a workspace, returns ready to use token // send credentials, returns empty valid token
rpc Login (WorkspaceJoinRequest) returns (Token); rpc Login (LoginRequest) returns (common.Token);
// if given token has just expired, get a new valid one
rpc Refresh (common.Token) returns (common.Token);
} }
message Token { message LoginRequest {
required string token = 1;
}
// TODO one-request-to-do-it-all from login to workspace access
message WorkspaceJoinRequest {
required string username = 1; required string username = 1;
required string password = 2; required string password = 2;
optional string workspace_id = 3;
} }

View file

@ -2,15 +2,20 @@ syntax = "proto2";
package common; package common;
// authentication token, probably a JWT but should be treated as a raw string
message Token {
required string token = 1;
}
// a wrapper payload representing an uuid // a wrapper payload representing an uuid
message Identity { message Identity {
required uint64 hi = 1; required uint64 hi = 1;
required uint64 lo = 2; required uint64 lo = 2;
} }
// a collection of identities message User {
message IdentityList { required Identity id = 1;
repeated Identity users = 1; optional string name = 2;
} }
//generic Empty message //generic Empty message

28
proto/session.proto Normal file
View file

@ -0,0 +1,28 @@
syntax = "proto2";
package session;
import "common.proto";
// manage user workspaces, refresh tokens
service Session {
rpc AccessWorkspace (WorkspaceRequest) returns (common.Token);
rpc CreateWorkspace (WorkspaceRequest) returns (common.Empty);
rpc DeleteWorkspace (WorkspaceRequest) returns (common.Empty);
rpc ListWorkspaces (common.Empty) returns (WorkspaceList);
rpc InviteToWorkspace (InviteRequest) returns (common.Empty);
}
message WorkspaceRequest {
required string workspace = 1;
}
message WorkspaceList {
repeated string owned = 1;
repeated string invited = 2;
}
message InviteRequest {
required string user = 1;
required string workspace = 2;
}

View file

@ -4,26 +4,29 @@ package workspace;
import "common.proto"; import "common.proto";
import "files.proto"; import "files.proto";
import "auth.proto";
service Workspace { service Workspace {
rpc Attach (common.Empty) returns (stream WorkspaceEvent); rpc Attach (common.Empty) returns (stream WorkspaceEvent);
rpc CreateBuffer (files.BufferNode) returns (common.Empty); rpc CreateBuffer (files.BufferNode) returns (common.Empty);
rpc AccessBuffer (files.BufferNode) returns (BufferCredentials); rpc AccessBuffer (files.BufferNode) returns (common.Token);
rpc DeleteBuffer (files.BufferNode) returns (common.Empty); rpc DeleteBuffer (files.BufferNode) returns (common.Empty);
rpc ListBuffers (common.Empty) returns (files.BufferTree); rpc ListBuffers (common.Empty) returns (files.BufferTree);
rpc ListUsers (common.Empty) returns (common.IdentityList); rpc ListUsers (common.Empty) returns (UserList);
rpc ListBufferUsers (files.BufferNode) returns (common.IdentityList); rpc ListBufferUsers (files.BufferNode) returns (UserList);
}
message UserList {
repeated common.User users = 1;
} }
message WorkspaceEvent { message WorkspaceEvent {
message UserJoin { message UserJoin {
required common.Identity user = 1; required common.User user = 1;
} }
message UserLeave { message UserLeave {
required common.Identity user = 1; required common.User user = 1;
} }
message FileCreate { message FileCreate {
required string path = 1; required string path = 1;
@ -44,11 +47,3 @@ message WorkspaceEvent {
FileDelete delete = 5; FileDelete delete = 5;
} }
} }
// TODO this is very ugly because we can't just return a new token (which is already smelly but whatev), we also need to tell the underlying id so that
// the client can put it as metadata while attaching, because it can't really know the underlying id that the server is using for each buffer without
// parsing the token itself. meehhhhhh, this bleeds underlying implementation to the upper levels, how can we avoid this??
message BufferCredentials {
required common.Identity id = 1;
required auth.Token token = 2;
}

View file

@ -27,6 +27,12 @@ pub mod common {
uuid::Uuid::from_u64_pair(value.hi, value.lo) uuid::Uuid::from_u64_pair(value.hi, value.lo)
} }
} }
impl Identity {
pub fn uuid(&self) -> uuid::Uuid {
uuid::Uuid::from(self)
}
}
} }
pub mod files { pub mod files {
@ -87,6 +93,10 @@ pub mod workspace {
tonic::include_proto!("workspace"); tonic::include_proto!("workspace");
} }
pub mod session {
tonic::include_proto!("session");
}
pub mod auth { pub mod auth {
tonic::include_proto!("auth"); tonic::include_proto!("auth");
} }