2023-03-12 16:00:57 +01:00
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// 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/>.
2022-10-08 13:49:56 +02:00
package auth
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
2023-01-02 13:10:50 +01:00
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
2022-10-08 13:49:56 +02:00
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
func ( m * Module ) OobHandler ( c * gin . Context ) {
2023-02-02 14:08:13 +01:00
instance , errWithCode := m . processor . InstanceGetV1 ( c . Request . Context ( ) )
2022-10-08 13:49:56 +02:00
if errWithCode != nil {
2023-02-02 14:08:13 +01:00
apiutil . ErrorHandler ( c , errWithCode , m . processor . InstanceGetV1 )
2022-10-08 13:49:56 +02:00
return
}
2023-02-02 14:08:13 +01:00
instanceGet := func ( ctx context . Context ) ( * apimodel . InstanceV1 , gtserror . WithCode ) {
2023-01-02 13:10:50 +01:00
return instance , nil
}
2022-10-08 13:49:56 +02:00
oobToken := c . Query ( "code" )
if oobToken == "" {
err := errors . New ( "no 'code' query value provided in callback redirect" )
2023-01-02 13:10:50 +01:00
apiutil . ErrorHandler ( c , gtserror . NewErrorBadRequest ( err , err . Error ( ) , oauth . HelpfulAdvice ) , instanceGet )
2022-10-08 13:49:56 +02:00
return
}
s := sessions . Default ( c )
errs := [ ] string { }
scope , ok := s . Get ( sessionScope ) . ( string )
if ! ok {
errs = append ( errs , fmt . Sprintf ( "key %s was not found in session" , sessionScope ) )
}
userID , ok := s . Get ( sessionUserID ) . ( string )
if ! ok {
errs = append ( errs , fmt . Sprintf ( "key %s was not found in session" , sessionUserID ) )
}
if len ( errs ) != 0 {
errs = append ( errs , oauth . HelpfulAdvice )
2023-02-02 14:08:13 +01:00
apiutil . ErrorHandler ( c , gtserror . NewErrorBadRequest ( errors . New ( "one or more missing keys on session during OobHandler" ) , errs ... ) , m . processor . InstanceGetV1 )
2022-10-08 13:49:56 +02:00
return
}
user , err := m . db . GetUserByID ( c . Request . Context ( ) , userID )
if err != nil {
m . clearSession ( s )
safe := fmt . Sprintf ( "user with id %s could not be retrieved" , userID )
var errWithCode gtserror . WithCode
if err == db . ErrNoEntries {
errWithCode = gtserror . NewErrorBadRequest ( err , safe , oauth . HelpfulAdvice )
} else {
errWithCode = gtserror . NewErrorInternalError ( err , safe , oauth . HelpfulAdvice )
}
2023-01-02 13:10:50 +01:00
apiutil . ErrorHandler ( c , errWithCode , instanceGet )
2022-10-08 13:49:56 +02:00
return
}
acct , err := m . db . GetAccountByID ( c . Request . Context ( ) , user . AccountID )
if err != nil {
m . clearSession ( s )
safe := fmt . Sprintf ( "account with id %s could not be retrieved" , user . AccountID )
var errWithCode gtserror . WithCode
if err == db . ErrNoEntries {
errWithCode = gtserror . NewErrorBadRequest ( err , safe , oauth . HelpfulAdvice )
} else {
errWithCode = gtserror . NewErrorInternalError ( err , safe , oauth . HelpfulAdvice )
}
2023-01-02 13:10:50 +01:00
apiutil . ErrorHandler ( c , errWithCode , instanceGet )
2022-10-08 13:49:56 +02:00
return
}
// we're done with the session now, so just clear it out
m . clearSession ( s )
c . HTML ( http . StatusOK , "oob.tmpl" , gin . H {
"instance" : instance ,
"user" : acct . Username ,
"oobToken" : oobToken ,
"scope" : scope ,
} )
}