package indieauth import ( "encoding/json" "fmt" "io" "net/http" "github.com/owncast/owncast/models" ia "github.com/owncast/owncast/services/auth/indieauth" "github.com/owncast/owncast/services/chat" "github.com/owncast/owncast/storage/chatrepository" "github.com/owncast/owncast/storage/configrepository" "github.com/owncast/owncast/storage/userrepository" "github.com/owncast/owncast/webserver/responses" log "github.com/sirupsen/logrus" ) type IndieAuthHandlers struct { configRepository *configrepository.SqlConfigRepository chatService *chat.Chat chatRepository *chatrepository.ChatRepository userRepository *userrepository.SqlUserRepository } // New creates a new instances of web server handlers. func New() *IndieAuthHandlers { return &IndieAuthHandlers{ configRepository: configrepository.Get(), chatService: chat.Get(), chatRepository: chatrepository.Get(), userRepository: userrepository.Get(), } } // StartAuthFlow will begin the IndieAuth flow for the current user. func (h *IndieAuthHandlers) StartAuthFlow(u models.User, w http.ResponseWriter, r *http.Request) { type request struct { AuthHost string `json:"authHost"` } type response struct { Redirect string `json:"redirect"` } var authRequest request p, err := io.ReadAll(r.Body) if err != nil { responses.WriteSimpleResponse(w, false, err.Error()) return } if err := json.Unmarshal(p, &authRequest); err != nil { responses.WriteSimpleResponse(w, false, err.Error()) return } accessToken := r.URL.Query().Get("accessToken") indieAuthClient := ia.GetIndieAuthClient() redirectURL, err := indieAuthClient.StartAuthFlow(authRequest.AuthHost, u.ID, accessToken, u.DisplayName) if err != nil { responses.WriteSimpleResponse(w, false, err.Error()) return } redirectResponse := response{ Redirect: redirectURL.String(), } responses.WriteResponse(w, redirectResponse) } // HandleRedirect will handle the redirect from an IndieAuth server to // continue the auth flow. func (h *IndieAuthHandlers) HandleRedirect(w http.ResponseWriter, r *http.Request) { indieAuthClient := ia.GetIndieAuthClient() state := r.URL.Query().Get("state") code := r.URL.Query().Get("code") request, response, err := indieAuthClient.HandleCallbackCode(code, state) if err != nil { log.Debugln(err) msg := `Unable to complete authentication. Go back.