mirror of
https://github.com/writefreely/writefreely
synced 2024-11-10 03:24:11 +00:00
#514 - Fix login with Gitea OAuth problems: external user ID not properly recorded.
This commit is contained in:
parent
a122e4e98a
commit
97a5121924
2 changed files with 33 additions and 8 deletions
10
oauth.go
10
oauth.go
|
@ -293,10 +293,15 @@ func configureGiteaOauth(parentHandler *Handler, r *mux.Router, app *App) {
|
|||
ClientID: app.Config().GiteaOauth.ClientID,
|
||||
ClientSecret: app.Config().GiteaOauth.ClientSecret,
|
||||
ExchangeLocation: app.Config().GiteaOauth.Host + "/login/oauth/access_token",
|
||||
InspectLocation: app.Config().GiteaOauth.Host + "/api/v1/user",
|
||||
InspectLocation: app.Config().GiteaOauth.Host + "/login/oauth/userinfo",
|
||||
AuthLocation: app.Config().GiteaOauth.Host + "/login/oauth/authorize",
|
||||
HttpClient: config.DefaultHTTPClient(),
|
||||
CallbackLocation: callbackLocation,
|
||||
Scope: "openid profile email",
|
||||
MapUserID: "sub",
|
||||
MapUsername: "login",
|
||||
MapDisplayName: "full_name",
|
||||
MapEmail: "email",
|
||||
}
|
||||
configureOauthRoutes(parentHandler, r, app, oauthClient, callbackProxy)
|
||||
}
|
||||
|
@ -355,7 +360,7 @@ func (h oauthHandler) viewOauthCallback(app *App, w http.ResponseWriter, r *http
|
|||
}
|
||||
|
||||
if localUserID != -1 && attachUserID > 0 {
|
||||
if err = addSessionFlash(app, w, r, "This Slack account is already attached to another user.", nil); err != nil {
|
||||
if err = addSessionFlash(app, w, r, "This OAuth account is already attached to another user.", nil); err != nil {
|
||||
return impart.HTTPError{Status: http.StatusInternalServerError, Message: err.Error()}
|
||||
}
|
||||
return impart.HTTPError{http.StatusFound, "/me/settings"}
|
||||
|
@ -376,6 +381,7 @@ func (h oauthHandler) viewOauthCallback(app *App, w http.ResponseWriter, r *http
|
|||
}
|
||||
if attachUserID > 0 {
|
||||
log.Info("attaching to user %d", attachUserID)
|
||||
log.Info("OAuth userid: %s", tokenInfo.UserID)
|
||||
err = h.DB.RecordRemoteUserID(r.Context(), attachUserID, tokenInfo.UserID, provider, clientID, tokenResponse.AccessToken)
|
||||
if err != nil {
|
||||
return impart.HTTPError{http.StatusInternalServerError, err.Error()}
|
||||
|
|
|
@ -3,6 +3,8 @@ package writefreely
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/writeas/web-core/log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -15,6 +17,11 @@ type giteaOauthClient struct {
|
|||
ExchangeLocation string
|
||||
InspectLocation string
|
||||
CallbackLocation string
|
||||
Scope string
|
||||
MapUserID string
|
||||
MapUsername string
|
||||
MapDisplayName string
|
||||
MapEmail string
|
||||
HttpClient HttpClient
|
||||
}
|
||||
|
||||
|
@ -46,7 +53,7 @@ func (c giteaOauthClient) buildLoginURL(state string) (string, error) {
|
|||
q.Set("redirect_uri", c.CallbackLocation)
|
||||
q.Set("response_type", "code")
|
||||
q.Set("state", state)
|
||||
// q.Set("scope", "read_user")
|
||||
q.Set("scope", c.Scope)
|
||||
u.RawQuery = q.Encode()
|
||||
return u.String(), nil
|
||||
}
|
||||
|
@ -55,7 +62,7 @@ func (c giteaOauthClient) exchangeOauthCode(ctx context.Context, code string) (*
|
|||
form := url.Values{}
|
||||
form.Add("grant_type", "authorization_code")
|
||||
form.Add("redirect_uri", c.CallbackLocation)
|
||||
// form.Add("scope", "read_user")
|
||||
form.Add("scope", c.Scope)
|
||||
form.Add("code", code)
|
||||
req, err := http.NewRequest("POST", c.ExchangeLocation, strings.NewReader(form.Encode()))
|
||||
if err != nil {
|
||||
|
@ -103,12 +110,24 @@ func (c giteaOauthClient) inspectOauthAccessToken(ctx context.Context, accessTok
|
|||
return nil, errors.New("unable to inspect access token")
|
||||
}
|
||||
|
||||
var inspectResponse InspectResponse
|
||||
if err := limitedJsonUnmarshal(resp.Body, infoRequestMaxLen, &inspectResponse); err != nil {
|
||||
// since we don't know what the JSON from the server will look like, we create a
|
||||
// generic interface and then map manually to values set in the config
|
||||
var genericInterface map[string]interface{}
|
||||
if err := limitedJsonUnmarshal(resp.Body, infoRequestMaxLen, &genericInterface); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if inspectResponse.Error != "" {
|
||||
return nil, errors.New(inspectResponse.Error)
|
||||
|
||||
// map each relevant field in inspectResponse to the mapped field from the config
|
||||
var inspectResponse InspectResponse
|
||||
inspectResponse.UserID, _ = genericInterface[c.MapUserID].(string)
|
||||
// log.Info("Userid from Gitea: %s", inspectResponse.UserID)
|
||||
if inspectResponse.UserID == "" {
|
||||
log.Error("[CONFIGURATION ERROR] Gitea OAuth provider returned empty UserID value (`%s`).\n Do you need to configure a different `map_user_id` value for this provider?", c.MapUserID)
|
||||
return nil, fmt.Errorf("no UserID (`%s`) value returned", c.MapUserID)
|
||||
}
|
||||
inspectResponse.Username, _ = genericInterface[c.MapUsername].(string)
|
||||
inspectResponse.DisplayName, _ = genericInterface[c.MapDisplayName].(string)
|
||||
inspectResponse.Email, _ = genericInterface[c.MapEmail].(string)
|
||||
|
||||
return &inspectResponse, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue