340 lines
9.4 KiB
Perl
340 lines
9.4 KiB
Perl
#!/usr/bin/perl
|
|
#
|
|
# DW::Controller::API::REST::Journals
|
|
#
|
|
# API controls for fetching journal-related information
|
|
#
|
|
# Authors:
|
|
# Ruth Hatch <ruth.s.hatch@gmail.com>
|
|
#
|
|
# Copyright (c) 2017 by Dreamwidth Studios, LLC.
|
|
#
|
|
# This program is free software; you may redistribute it and/or modify it under
|
|
# the same terms as Perl itself. For a copy of the license, please reference
|
|
# 'perldoc perlartistic' or 'perldoc perlgpl'.
|
|
#
|
|
|
|
package DW::Controller::API::REST::Journals;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use DW::Routing;
|
|
use DW::Request;
|
|
use DW::Controller;
|
|
use DW::API::RateLimit;
|
|
use JSON;
|
|
use Data::Dumper;
|
|
|
|
################################################
|
|
# /journals/{journal}/accesslists
|
|
#
|
|
# Get a list of accesslists, or create a new accesslist
|
|
################################################
|
|
|
|
my $accesslists_all = DW::Controller::API::REST->path(
|
|
'journals/accesslists_all.yaml',
|
|
1,
|
|
{
|
|
get => DW::API::RateLimit->wrap(
|
|
\&accesslists_get,
|
|
name => 'accesslists_get',
|
|
rate => '100/60s'
|
|
),
|
|
post => DW::API::RateLimit->wrap(
|
|
\&accesslists_new,
|
|
name => 'accesslists_post',
|
|
rate => '10/60s'
|
|
),
|
|
delete => DW::API::RateLimit->wrap(
|
|
\&accesslists_delete,
|
|
name => 'accesslists_delete',
|
|
rate => '10/60s'
|
|
)
|
|
}
|
|
);
|
|
|
|
sub accesslists_get {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my @trust_groups = $user->trust_groups;
|
|
my @accesslists = ();
|
|
|
|
#push the names and group ids of the user's trust groups to the list.
|
|
foreach my $group (@trust_groups) {
|
|
my $group_hash = { "id" => $group->{groupnum}, "name" => $group->{groupname} };
|
|
push( @accesslists, $group_hash );
|
|
}
|
|
|
|
return $self->rest_ok( \@accesslists );
|
|
}
|
|
|
|
sub accesslists_new {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $body = $args->{body};
|
|
$body->{sortorder} ||= 0;
|
|
|
|
my $group = $user->create_trust_group(
|
|
groupname => $body->{name},
|
|
sortorder => $body->{sortorder}
|
|
);
|
|
|
|
return $self->rest_ok( { id => $group } );
|
|
}
|
|
|
|
sub accesslists_delete {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $id = $args->{query}{id};
|
|
|
|
my $group = $user->delete_trust_group( { id => $id } );
|
|
|
|
return $self->rest_ok();
|
|
}
|
|
|
|
################################################
|
|
# /journals/{journal}/accesslists/{id}
|
|
#
|
|
# Get details about a specific accesslist
|
|
################################################
|
|
|
|
my $accesslists = DW::Controller::API::REST->path(
|
|
'journals/accesslists.yaml',
|
|
1,
|
|
{
|
|
get => DW::API::RateLimit->wrap(
|
|
\&accesslist_get,
|
|
name => 'accesslist_get',
|
|
rate => '100/60s'
|
|
),
|
|
post => DW::API::RateLimit->wrap(
|
|
\&accesslist_edit,
|
|
name => 'accesslist_edit',
|
|
rate => '10/60s'
|
|
)
|
|
}
|
|
);
|
|
|
|
sub accesslist_get {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $id = $args->{path}{accesslistid};
|
|
my $group_members = $user->trust_group_members( id => $id );
|
|
return $self->rest_error( "400", "Access filter doesn't exist." ) unless $group_members;
|
|
my @accesslist;
|
|
my $members = LJ::load_userids( keys %$group_members );
|
|
|
|
#push the names and group ids of the user's trust groups to the list.
|
|
foreach my $userid ( keys %$members ) {
|
|
my $name = $members->{$userid}->user;
|
|
push( @accesslist, $name );
|
|
}
|
|
|
|
return $self->rest_ok( \@accesslist );
|
|
}
|
|
|
|
sub accesslist_edit {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $journals = $args->{body}{journals};
|
|
my $id = $args->{path}{accesslistid};
|
|
|
|
my $trust_group = $user->trust_groups( { id => $id } );
|
|
return $self->rest_error( "400", "Access filter doesn't exist." ) unless $trust_group;
|
|
|
|
foreach my $journal ( @{$journals} ) {
|
|
my $trusted_u = LJ::load_user($journal);
|
|
|
|
# User might have been removed from circle between load and
|
|
# submit; don't re-add.
|
|
next unless $trusted_u && $user->trusts($trusted_u);
|
|
$user->edit_trustmask( $trusted_u, add => $id );
|
|
}
|
|
return $self->rest_ok();
|
|
}
|
|
|
|
sub accesslist_delete {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $journals = $args->{query}{journal};
|
|
my $id = $args->{path}{accesslistid};
|
|
|
|
my $trust_group = $user->trust_groups( { id => $id } );
|
|
return $self->rest_error( "400", "Access filter doesn't exist." ) unless $trust_group;
|
|
|
|
foreach my $journal ( @{$journals} ) {
|
|
my $trusted_u = LJ::load_user($journal);
|
|
|
|
# User might have been removed from circle between load and
|
|
# submit; don't re-add.
|
|
next unless $trusted_u && $user->trusts($trusted_u);
|
|
$user->edit_trustmask( $trusted_u, remove => $id );
|
|
}
|
|
return $self->rest_ok();
|
|
}
|
|
################################################
|
|
# /journals/{journal}/tags
|
|
#
|
|
# Get a list of tags, create new tags, or delete tags
|
|
################################################
|
|
|
|
my $tags = DW::Controller::API::REST->path(
|
|
'journals/tags.yaml',
|
|
1,
|
|
{
|
|
get => DW::API::RateLimit->wrap(
|
|
\&tags_get,
|
|
name => 'tags_get',
|
|
rate => '100/60s'
|
|
),
|
|
post => DW::API::RateLimit->wrap(
|
|
\&tags_post,
|
|
name => 'tags_post',
|
|
rate => '10/60s'
|
|
),
|
|
delete => DW::API::RateLimit->wrap(
|
|
\&tags_delete,
|
|
name => 'tags_delete',
|
|
rate => '10/60s'
|
|
)
|
|
}
|
|
);
|
|
|
|
sub tags_get {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
|
|
# get tags for the page to display
|
|
my @taglist;
|
|
my $tags = LJ::Tags::get_usertags( $user, { remote => $remote } );
|
|
foreach my $kwid ( keys %{$tags} ) {
|
|
|
|
# only show tags for display
|
|
next unless $tags->{$kwid}->{display};
|
|
my $tag = LJ::S2::TagDetail( $user, $kwid => $tags->{$kwid} );
|
|
|
|
# delete some fields the enduser doesn't need
|
|
delete $tag->{_type};
|
|
delete $tag->{_id};
|
|
push @taglist, $tag;
|
|
}
|
|
@taglist = sort { $a->{name} cmp $b->{name} } @taglist;
|
|
|
|
return $self->rest_ok( \@taglist );
|
|
}
|
|
|
|
sub tags_post {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $tagerr = "";
|
|
my @errors;
|
|
|
|
my $tags = $args->{body};
|
|
|
|
#push the usernames for all comms the user has posting access to onto the list.
|
|
foreach my $tag ( @{$tags} ) {
|
|
|
|
my $rv = LJ::Tags::create_usertag( $user, $tag, { display => 1, err_ref => \$tagerr } );
|
|
push @errors, $tagerr unless $rv;
|
|
}
|
|
|
|
return $self->rest_error( 'GET', 400 ) if $#errors > 0;
|
|
return $self->rest_ok();
|
|
}
|
|
|
|
sub tags_delete {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my $tag = $args->{query}{tag};
|
|
|
|
LJ::Tags::delete_usertag( $user, 'name', $tag );
|
|
|
|
return $self->rest_ok();
|
|
}
|
|
|
|
################################################
|
|
# /journals/{journal}/xpostaccounts
|
|
#
|
|
# Get a list of crosspost accounts
|
|
################################################
|
|
|
|
my $xpost = DW::Controller::API::REST->path(
|
|
'journals/xpostaccounts.yaml',
|
|
1,
|
|
{
|
|
get => DW::API::RateLimit->wrap(
|
|
\&xpost_get,
|
|
name => 'xpost_get',
|
|
rate => '100/60s'
|
|
)
|
|
}
|
|
);
|
|
|
|
sub xpost_get {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $user = LJ::load_user( $args->{path}{username} );
|
|
my $remote = $args->{user};
|
|
return $self->rest_error("404") unless $user;
|
|
return $self->rest_error("403") unless $user == $remote;
|
|
|
|
my @xpostaccounts = DW::External::Account->get_external_accounts($user);
|
|
my @accountlist;
|
|
|
|
#FIXME: print minsecurity as well? Weird encoding bugs though.
|
|
foreach my $account (@xpostaccounts) {
|
|
my $accounthash = {
|
|
name => $account->displayname,
|
|
xpostbydefault => $account->{xpostbydefault}
|
|
};
|
|
push @accountlist, $accounthash;
|
|
|
|
}
|
|
|
|
return $self->rest_ok( \@accountlist );
|
|
}
|
|
|
|
1;
|