Skip to content
Snippets Groups Projects
Verified Commit 3a94f5f1 authored by Gabriel Zachmann's avatar Gabriel Zachmann
Browse files

obtain email from OP and store it in db

parent 3866ae77
No related branches found
No related tags found
No related merge requests found
......@@ -569,15 +569,12 @@ BEGIN
WHERE u.id = (SELECT m.user_id FROM MTokens m WHERE m.id = MTID);
END;;
CREATE OR REPLACE PROCEDURE Users_SetMail(IN UID BIGINT UNSIGNED, IN MAIL TEXT, IN VERIFIED BIT)
CREATE OR REPLACE PROCEDURE Users_SetMail(IN MTID VARCHAR(128), IN MAIL TEXT, IN VERIFIED BIT)
BEGIN
UPDATE Users u SET u.email=MAIL, u.email_verified=VERIFIED WHERE u.id = UID;
END;;
CREATE OR REPLACE PROCEDURE Users_SetMailBySub(IN SUB TEXT, IN ISS TEXT, IN MAIL TEXT, IN VERIFIED BIT)
BEGIN
CALL Users_GetID(SUB, ISS, @UID);
CALL Users_SetMail(@UID, MAIL, VERIFIED);
UPDATE Users u
SET u.email=MAIL,
u.email_verified=VERIFIED
WHERE u.id = (SELECT m.user_id FROM MTokens m WHERE m.id = MTID);
END;;
CREATE OR REPLACE PROCEDURE getOIDCIssForManagementCode(IN CODE VARCHAR(128))
......
......@@ -44,3 +44,13 @@ func ChangePreferredMailType(rlog log.Ext1FieldLogger, tx *sqlx.Tx, mtID mtid.MT
},
)
}
// SetEmail sets a user's email address
func SetEmail(rlog log.Ext1FieldLogger, tx *sqlx.Tx, mtID mtid.MTID, mail string, mailVerified bool) error {
return db.RunWithinTransaction(
rlog, tx, func(tx *sqlx.Tx) error {
_, err := tx.Exec(`CALL Users_SetMail(?,?,?)`, mtID, mail, mailVerified)
return errors.WithStack(err)
},
)
}
......@@ -23,6 +23,7 @@ import (
"github.com/oidc-mytoken/server/internal/db/dbrepo/authcodeinforepo/state"
"github.com/oidc-mytoken/server/internal/db/dbrepo/mytokenrepo"
"github.com/oidc-mytoken/server/internal/db/dbrepo/mytokenrepo/transfercoderepo"
"github.com/oidc-mytoken/server/internal/db/dbrepo/userrepo"
response "github.com/oidc-mytoken/server/internal/endpoints/token/mytoken/pkg"
"github.com/oidc-mytoken/server/internal/model"
mytoken "github.com/oidc-mytoken/server/internal/mytoken/pkg"
......@@ -30,6 +31,7 @@ import (
"github.com/oidc-mytoken/server/internal/oidc/oidcreqres"
"github.com/oidc-mytoken/server/internal/oidc/pkce"
provider2 "github.com/oidc-mytoken/server/internal/oidc/provider"
"github.com/oidc-mytoken/server/internal/oidc/userinfo"
"github.com/oidc-mytoken/server/internal/server/httpstatus"
"github.com/oidc-mytoken/server/internal/server/routes"
iutils "github.com/oidc-mytoken/server/internal/utils"
......@@ -248,6 +250,17 @@ func CodeExchange(
return err
}
}
mailInfo, err := userrepo.GetMail(rlog, tx, ste.ID)
_, err = db.ParseError(err)
if err != nil {
return err
}
if !mailInfo.Mail.Valid {
mail, mailVerified := extractMail(rlog, oidcTokenRes, p)
if err = userrepo.SetEmail(rlog, tx, ste.ID, mail, mailVerified); err != nil {
return err
}
}
return authcodeinforepo.DeleteAuthFlowInfoByState(rlog, tx, oState)
},
); err != nil {
......@@ -282,6 +295,31 @@ func CodeExchange(
}
}
func extractMail(rlog log.Ext1FieldLogger, oidcTokenRes *oidcreqres.OIDCTokenResponse, provider model.Provider) (
mail string,
verified bool,
) {
var ok bool
mail, ok = jwtutils.GetStringFromJWT(rlog, oidcTokenRes.IDToken, "email")
if ok {
verified = true
return
}
mail, ok = jwtutils.GetStringFromJWT(rlog, oidcTokenRes.AccessToken, "email")
if ok {
verified = true
return
}
userinfoRes, errRes, err := userinfo.Get(provider, oidcTokenRes.AccessToken)
if err != nil || errRes != nil {
mail = ""
return
}
mail, _ = userinfoRes["email"].(string)
verified, _ = userinfoRes["email_verified"].(bool)
return
}
func createMytokenEntry(
rlog log.Ext1FieldLogger, tx *sqlx.Tx, authFlowInfo *authcodeinforepo.AuthFlowInfoOut, rt,
oidcSub string, networkData api.ClientMetaData,
......
package userinfo
import (
"github.com/oidc-mytoken/utils/httpclient"
"github.com/pkg/errors"
"github.com/oidc-mytoken/server/internal/model"
"github.com/oidc-mytoken/server/internal/oidc/oidcreqres"
)
// Get obtains the userinfo response from the model.Provider's userinfo endpoint
func Get(
provider model.Provider, at string,
) (map[string]any, *oidcreqres.OIDCErrorResponse, error) {
httpRes, err := httpclient.Do().R().
SetAuthToken(at).
SetResult(make(map[string]any)).
SetError(&oidcreqres.OIDCErrorResponse{}).
Get(provider.Endpoints().Userinfo)
if err != nil {
return nil, nil, errors.WithStack(err)
}
if errRes, ok := httpRes.Error().(*oidcreqres.OIDCErrorResponse); ok && errRes != nil && errRes.Error != "" {
errRes.Status = httpRes.RawResponse.StatusCode
return nil, errRes, nil
}
res, ok := httpRes.Result().(map[string]any)
if !ok {
return nil, nil, errors.New("could not unmarshal userinfo response")
}
return res, nil, nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment