2022-10-08 13:49:56 +02:00
/ *
GoToSocial
2023-01-05 12:43:00 +01:00
Copyright ( C ) 2021 - 2023 GoToSocial Authors admin @ gotosocial . org
2022-10-08 13:49:56 +02: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 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 ,
} )
}