package SeMeet::Controller::Meets; use Mojo::Base 'Mojolicious::Controller', -signatures; use UUID::URandom qw(create_uuid_string); use Mojo::JWT; use constant AVATAR_SIZE => 320; use constant JITSI_TOKEN_LIFETIME => 3600 * 24; sub create($c) { $c->openapi->valid_input or return; my $args = $c->req->json; return $c->error(403, 'Access denied') if ! $c->stash->{permissions}{create}; my $exists = $c->schema->resultset('Meet')->count({ deleted => undef, name => $args->{name}, }); return $c->error(400, 'DUPLICTE_NAME') if $exists; my $guard = $c->schema->txn_scope_guard; my $meet = $c->schema->resultset('Meet')->create({ uuid => create_uuid_string(), owner_id => $c->stash->{user}->id, name => $args->{name}, }); $guard->commit; $c->trace(\'User %s create meet "%s" with id %d', $c->stash->{user}->username, $meet->name, $meet->id, ); $c->render( status => 201, openapi => { id => $meet->id }, ); } sub get($c) { $c->openapi->valid_input or return; my $args = $c->req->json; my $meet = $c->_get($c->stash->{id}, 0) // return; my $users = { 0 => [], 1 => [] }; my @invites = (); USER: foreach my $user ( $meet->users ) { push @{ $users->{ $user->is_moderator} }, { id => $user->id, name => $user->user_name, } } INVITE: foreach my $invite ( $meet->invites ) { push @invites, { id => $invite->id, token => $invite->token, displayname => $invite->displayname, } } $c->render(openapi => $c->spec_filter({ $meet->get_columns, groups => $meet->cached_groups, #TODO: direct moderators => $users->{1}, participants => $users->{0}, invites => \@invites, }, 'Meet')); } sub list($c) { $c->openapi->valid_input or return; my $args = $c->req->json; my $meets = $c->schema->resultset('Meet')->search({ deleted => undef, -or => [ owner_id => $c->stash->{user}->id, "meet_groups.group_id" => { '-in' => $c->stash->{groups} }, "meet_users.user_id" => $c->stash->{user}->id, ] }, { order_by => 'name', join => ['meet_groups', 'meet_users'], distinct => 1, } ); my @meets = (); MEET: while ( my $meet = $meets->next()) { push @meets, $c->spec_filter({ $meet->get_columns, groups => $meet->cached_groups, moderators => $meet->cached_moderators, participants => [], invites => [], }, 'Meet') } $c->render( openapi => { count => scalar( @meets ), records => \@meets, }, ); } sub add_groups($c) { $c->openapi->valid_input or return; my $args = $c->req->json; my $meet = $c->_get($c->stash->{id}, 1) // return; IDS: foreach my $id ( @{ $args->{groups} } ) { $meet->find_or_create_related('meet_groups', { group_id => $id } ); } $meet->update_groups_cache(); $c->render( status => 204, text => '' ); } sub delete_group($c) { $c->openapi->valid_input or return; my $meet = $c->_get($c->stash->{id}, 1) // return; $meet->delete_related('meet_groups', { group_id => $c->stash->{group_id} } ); $meet->update_groups_cache(); $c->render( status => 204, text => '' ); } sub add_users($c) { $c->openapi->valid_input or return; my $args = $c->req->json; my $meet = $c->_get($c->stash->{id}, 2) // return; my $is_moderator = $args->{kind} eq 'moderator' ? 't':'f'; UUID: foreach my $uuid ( @{ $args->{users} } ) { my $user = $c->user_by_uuid($uuid) // next UUID; $meet->find_or_create_related('meet_users', { user_id => $user->id, is_moderator => $is_moderator, } ); } $meet->update_moderators_cache() if $is_moderator; $c->render( status => 204, text => '' ); } sub delete_user($c) { $c->openapi->valid_input or return; my $meet = $c->_get($c->stash->{id}, 2) // return; $meet->delete_related('meet_users', { id => $c->stash->{relation_id} } ); $meet->update_moderators_cache(); $c->render( status => 204, text => '' ); } sub delete_invite($c) { $c->openapi->valid_input or return; my $meet = $c->_get($c->stash->{id}, 2) // return; $meet->delete_related('invites', { id => $c->stash->{invite_id} } ); $c->render( status => 204, text => '' ); } sub delete($c) { $c->openapi->valid_input or return; my $meet = $c->_get($c->stash->{id}, 2) // return; $meet->update({ deleted => \'now()'}); $c->render( status => 204, text => '' ); } sub update($c) { $c->openapi->valid_input or return; my $args = $c->req->json; my $meet = $c->_get($c->stash->{id}, 2) // return; my $exists = $c->schema->resultset('Meet')->count({ id => { '!=' => $meet->id }, deleted => undef, name => $args->{name}, }); return $c->error(400, 'DUPLICTE_NAME') if $exists; $meet->update({ name => $args->{name}, description => $args->{description}, }); $c->render( status => 204, text => '' ); } sub meet($c) { #NENI API! my $meet = $c->schema->resultset('Meet')->find({ id => $c->stash->{id} }); my $user = $c->schema->resultset('User')->find({ id => $c->current_user->{id} }); if (! $meet) { $c->render('unauthorized'); return; } # return $c->error(404, 'NOT_FOUND') if ! $meet; my $roles = $meet->user_roles($user, $c->current_user->{groups}); $c->trace($roles); # return $c->error(404, 'NOT_FOUND') if ! $roles->{any}; if (! $roles->{any}) { $c->render('unauthorized'); return; } $c->stash->{meet} = $meet; $c->stash->{roles} = $roles; $c->stash->{token} = $user->meet_token($meet, $c->config); $c->render('meet'); } sub _get($c, $id, $access) { my $meet = $c->schema->resultset('Meet')->find({ id => $id }); return $c->error(404, 'NOT_FOUND') if ! $meet; my $roles = $meet->user_roles($c->stash->{user}, $c->stash->{groups}); return $c->error(403, 'ACCESS_DENIED') if ! $roles->{any}; if ( $access == 1 && ! ($roles->{moderator} || $roles->{owner}) ) { return $c->error(403, 'ACCESS_DENIED'); } if ( $access == 2 && ! $roles->{owner} ) { return $c->error(403, 'ACCESS_DENIED'); } return $meet; } 1;