mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-18 22:57:38 +01:00
Merge pull request #7567 from reasonerjt/oidc-google-refresh-token
Persist the new token in DB after login
This commit is contained in:
commit
7af679af7e
@ -148,8 +148,8 @@ func AuthCodeURL(state string) (string, error) {
|
|||||||
log.Errorf("Failed to get OAuth configuration, error: %v", err)
|
log.Errorf("Failed to get OAuth configuration, error: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(conf.Endpoint.AuthURL, googleEndpoint) {
|
if strings.HasPrefix(conf.Endpoint.AuthURL, googleEndpoint) { // make sure the refresh token will be returned
|
||||||
return conf.AuthCodeURL(state, oauth2.AccessTypeOffline), nil
|
return conf.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "consent")), nil
|
||||||
}
|
}
|
||||||
return conf.AuthCodeURL(state), nil
|
return conf.AuthCodeURL(state), nil
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,7 @@ func (dm *defaultManager) VerifyToken(ctx context.Context, user *models.OIDCUser
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return verifyError(err)
|
return verifyError(err)
|
||||||
}
|
}
|
||||||
|
log.Debugf("Token string for verify: %s", tokenStr)
|
||||||
_, err = VerifyToken(ctx, token.IDToken)
|
_, err = VerifyToken(ctx, token.IDToken)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
const tokenKey = "oidc_token"
|
const tokenKey = "oidc_token"
|
||||||
const stateKey = "oidc_state"
|
const stateKey = "oidc_state"
|
||||||
const userInfoKey = "oidc_user_info"
|
const userInfoKey = "oidc_user_info"
|
||||||
|
const oidcUserComment = "Onboarded via OIDC provider"
|
||||||
|
|
||||||
// OIDCController handles requests for OIDC login, callback and user onboard
|
// OIDCController handles requests for OIDC login, callback and user onboard
|
||||||
type OIDCController struct {
|
type OIDCController struct {
|
||||||
@ -67,6 +68,7 @@ func (oc *OIDCController) RedirectLogin() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
oc.SetSession(stateKey, state)
|
oc.SetSession(stateKey, state)
|
||||||
|
log.Debugf("State dumped to session: %s", state)
|
||||||
// Force to use the func 'Redirect' of beego.Controller
|
// Force to use the func 'Redirect' of beego.Controller
|
||||||
oc.Controller.Redirect(url, http.StatusFound)
|
oc.Controller.Redirect(url, http.StatusFound)
|
||||||
}
|
}
|
||||||
@ -75,6 +77,8 @@ func (oc *OIDCController) RedirectLogin() {
|
|||||||
// kick off onboard if needed.
|
// kick off onboard if needed.
|
||||||
func (oc *OIDCController) Callback() {
|
func (oc *OIDCController) Callback() {
|
||||||
if oc.Ctx.Request.URL.Query().Get("state") != oc.GetSession(stateKey) {
|
if oc.Ctx.Request.URL.Query().Get("state") != oc.GetSession(stateKey) {
|
||||||
|
log.Errorf("State mismatch, in session: %s, in url: %s", oc.GetSession(stateKey),
|
||||||
|
oc.Ctx.Request.URL.Query().Get("state"))
|
||||||
oc.SendBadRequestError(errors.New("State mismatch"))
|
oc.SendBadRequestError(errors.New("State mismatch"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -106,21 +110,34 @@ func (oc *OIDCController) Callback() {
|
|||||||
oc.SendInternalServerError(err)
|
oc.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenBytes, err := json.Marshal(token)
|
tokenBytes, err := json.Marshal(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
oc.SendInternalServerError(err)
|
oc.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debugf("Exchanged token string: %s", string(tokenBytes))
|
||||||
oc.SetSession(tokenKey, tokenBytes)
|
oc.SetSession(tokenKey, tokenBytes)
|
||||||
|
|
||||||
if u == nil {
|
if u == nil {
|
||||||
oc.SetSession(userInfoKey, string(ouDataStr))
|
oc.SetSession(userInfoKey, string(ouDataStr))
|
||||||
oc.Controller.Redirect("/oidc-onboard", http.StatusFound)
|
oc.Controller.Redirect(fmt.Sprintf("/oidc-onboard?username=%s", strings.Replace(d.Username, " ", "_", -1)),
|
||||||
|
http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
|
oidcUser, err := dao.GetOIDCUserByUserID(u.UserID)
|
||||||
|
if err != nil {
|
||||||
|
oc.SendInternalServerError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, t, err := secretAndToken(tokenBytes)
|
||||||
|
oidcUser.Token = t
|
||||||
|
if err := dao.UpdateOIDCUser(oidcUser); err != nil {
|
||||||
|
oc.SendInternalServerError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
oc.SetSession(userKey, *u)
|
oc.SetSession(userKey, *u)
|
||||||
oc.Controller.Redirect("/", http.StatusFound)
|
oc.Controller.Redirect("/", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Onboard handles the request to onboard an user authenticated via OIDC provider
|
// Onboard handles the request to onboard an user authenticated via OIDC provider
|
||||||
@ -170,18 +187,19 @@ func (oc *OIDCController) Onboard() {
|
|||||||
|
|
||||||
email := d.Email
|
email := d.Email
|
||||||
if email == "" {
|
if email == "" {
|
||||||
email = utils.GenerateRandomString() + "@harbor.com"
|
email = utils.GenerateRandomString() + "@placeholder.com"
|
||||||
}
|
}
|
||||||
user := models.User{
|
user := models.User{
|
||||||
Username: username,
|
Username: username,
|
||||||
Email: email,
|
Email: email,
|
||||||
OIDCUserMeta: &oidcUser,
|
OIDCUserMeta: &oidcUser,
|
||||||
|
Comment: oidcUserComment,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dao.OnBoardOIDCUser(&user)
|
err = dao.OnBoardOIDCUser(&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), dao.ErrDupUser.Error()) {
|
if strings.Contains(err.Error(), dao.ErrDupUser.Error()) {
|
||||||
oc.RenderError(http.StatusConflict, "Duplicate username")
|
oc.RenderError(http.StatusConflict, "Conflict in username, the user with same username has been onboarded.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
oc.SendInternalServerError(err)
|
oc.SendInternalServerError(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user