2021-10-24 12:57:39 +03:00
/ *
GoToSocial
2021-12-20 20:42:19 +03:00
Copyright ( C ) 2021 - 2022 GoToSocial Authors admin @ gotosocial . org
2021-10-24 12:57:39 +03:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Affero General Public License for more details .
You should have received a copy of the GNU Affero General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
package federation
import (
"context"
"fmt"
"net/url"
2021-11-13 19:29:43 +03:00
"github.com/superseriousbusiness/activity/streams"
2022-06-11 12:01:34 +03:00
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
2021-10-24 12:57:39 +03:00
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
2022-11-24 00:40:07 +03:00
"github.com/superseriousbusiness/gotosocial/internal/transport"
2021-10-24 12:57:39 +03:00
)
func ( p * processor ) GetStatus ( ctx context . Context , requestedUsername string , requestedStatusID string , requestURL * url . URL ) ( interface { } , gtserror . WithCode ) {
// get the account the request is referring to
2022-09-02 12:56:33 +03:00
requestedAccount , err := p . db . GetAccountByUsernameDomain ( ctx , requestedUsername , "" )
2021-10-24 12:57:39 +03:00
if err != nil {
return nil , gtserror . NewErrorNotFound ( fmt . Errorf ( "database error getting account with username %s: %s" , requestedUsername , err ) )
}
// authenticate the request
2022-04-26 19:10:11 +03:00
requestingAccountURI , errWithCode := p . federator . AuthenticateFederatedRequest ( ctx , requestedUsername )
if errWithCode != nil {
return nil , errWithCode
2021-10-24 12:57:39 +03:00
}
2022-11-24 00:40:07 +03:00
requestingAccount , err := p . federator . GetRemoteAccount ( transport . WithFastfail ( ctx ) , dereferencing . GetRemoteAccountParams {
2022-06-11 12:01:34 +03:00
RequestingUsername : requestedUsername ,
RemoteAccountID : requestingAccountURI ,
} )
2021-10-24 12:57:39 +03:00
if err != nil {
2022-06-08 21:38:03 +03:00
return nil , gtserror . NewErrorUnauthorized ( err )
2021-10-24 12:57:39 +03:00
}
// authorize the request:
// 1. check if a block exists between the requester and the requestee
blocked , err := p . db . IsBlocked ( ctx , requestedAccount . ID , requestingAccount . ID , true )
if err != nil {
return nil , gtserror . NewErrorInternalError ( err )
}
if blocked {
2022-06-08 21:38:03 +03:00
return nil , gtserror . NewErrorUnauthorized ( fmt . Errorf ( "block exists between accounts %s and %s" , requestedAccount . ID , requestingAccount . ID ) )
2021-10-24 12:57:39 +03:00
}
// get the status out of the database here
2022-05-02 13:53:46 +03:00
s , err := p . db . GetStatusByID ( ctx , requestedStatusID )
if err != nil {
2021-10-24 12:57:39 +03:00
return nil , gtserror . NewErrorNotFound ( fmt . Errorf ( "database error getting status with id %s and account id %s: %s" , requestedStatusID , requestedAccount . ID , err ) )
}
2022-05-02 13:53:46 +03:00
if s . AccountID != requestedAccount . ID {
return nil , gtserror . NewErrorNotFound ( fmt . Errorf ( "status with id %s does not belong to account with id %s" , s . ID , requestedAccount . ID ) )
}
2021-10-24 12:57:39 +03:00
visible , err := p . filter . StatusVisible ( ctx , s , requestingAccount )
if err != nil {
return nil , gtserror . NewErrorInternalError ( err )
}
if ! visible {
return nil , gtserror . NewErrorNotFound ( fmt . Errorf ( "status with id %s not visible to user with id %s" , s . ID , requestingAccount . ID ) )
}
// requester is authorized to view the status, so convert it to AP representation and serialize it
asStatus , err := p . tc . StatusToAS ( ctx , s )
if err != nil {
return nil , gtserror . NewErrorInternalError ( err )
}
data , err := streams . Serialize ( asStatus )
if err != nil {
return nil , gtserror . NewErrorInternalError ( err )
}
return data , nil
}