added signup link verification to oauth signup flow
Этот коммит содержится в:
79
api/user.go
79
api/user.go
@@ -81,36 +81,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
hash := r.URL.Query().Get("h")
|
hash := r.URL.Query().Get("h")
|
||||||
|
|
||||||
shouldVerifyHash := true
|
if IsVerifyHashRequired(user, team, hash) {
|
||||||
|
|
||||||
if team.Type == model.TEAM_INVITE && len(team.AllowedDomains) > 0 && len(hash) == 0 {
|
|
||||||
domains := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(team.AllowedDomains, "@", " ", -1), ",", " ", -1))))
|
|
||||||
|
|
||||||
matched := false
|
|
||||||
for _, d := range domains {
|
|
||||||
if strings.HasSuffix(user.Email, "@"+d) {
|
|
||||||
matched = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if matched {
|
|
||||||
shouldVerifyHash = false
|
|
||||||
} else {
|
|
||||||
c.Err = model.NewAppError("createUser", "The signup link does not appear to be valid", "allowed domains failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if team.Type == model.TEAM_OPEN {
|
|
||||||
shouldVerifyHash = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(hash) > 0 {
|
|
||||||
shouldVerifyHash = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if shouldVerifyHash {
|
|
||||||
data := r.URL.Query().Get("d")
|
data := r.URL.Query().Get("d")
|
||||||
props := model.MapFromJson(strings.NewReader(data))
|
props := model.MapFromJson(strings.NewReader(data))
|
||||||
|
|
||||||
@@ -147,6 +118,38 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsVerifyHashRequired(user *model.User, team *model.Team, hash string) bool {
|
||||||
|
shouldVerifyHash := true
|
||||||
|
|
||||||
|
if team.Type == model.TEAM_INVITE && len(team.AllowedDomains) > 0 && len(hash) == 0 && user != nil {
|
||||||
|
domains := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(team.AllowedDomains, "@", " ", -1), ",", " ", -1))))
|
||||||
|
|
||||||
|
matched := false
|
||||||
|
for _, d := range domains {
|
||||||
|
if strings.HasSuffix(user.Email, "@"+d) {
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if matched {
|
||||||
|
shouldVerifyHash = false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if team.Type == model.TEAM_OPEN {
|
||||||
|
shouldVerifyHash = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(hash) > 0 {
|
||||||
|
shouldVerifyHash = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return shouldVerifyHash
|
||||||
|
}
|
||||||
|
|
||||||
func CreateValet(c *Context, team *model.Team) *model.User {
|
func CreateValet(c *Context, team *model.Team) *model.User {
|
||||||
valet := &model.User{}
|
valet := &model.User{}
|
||||||
valet.TeamId = team.Id
|
valet.TeamId = team.Id
|
||||||
@@ -1223,21 +1226,7 @@ func getStatuses(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAuthorizationCode(c *Context, w http.ResponseWriter, r *http.Request, service, redirectUri string) {
|
func GetAuthorizationCode(c *Context, w http.ResponseWriter, r *http.Request, teamName, service, redirectUri string) {
|
||||||
params := mux.Vars(r)
|
|
||||||
teamName := params["team"]
|
|
||||||
|
|
||||||
if len(teamName) == 0 {
|
|
||||||
c.Err = model.NewAppError("GetAuthorizationCode", "Invalid team name", "team_name="+teamName)
|
|
||||||
c.Err.StatusCode = http.StatusBadRequest
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure team exists
|
|
||||||
if result := <-Srv.Store.Team().GetByName(teamName); result.Err != nil {
|
|
||||||
c.Err = result.Err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if s, ok := utils.Cfg.SSOSettings[service]; !ok || !s.Allow {
|
if s, ok := utils.Cfg.SSOSettings[service]; !ok || !s.Allow {
|
||||||
c.Err = model.NewAppError("GetAuthorizationCode", "Unsupported OAuth service provider", "service="+service)
|
c.Err = model.NewAppError("GetAuthorizationCode", "Unsupported OAuth service provider", "service="+service)
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ module.exports = React.createClass({
|
|||||||
<div className="form-group form-group--small">
|
<div className="form-group form-group--small">
|
||||||
<span></span>
|
<span></span>
|
||||||
</div>
|
</div>
|
||||||
<p>{"Choose your username and password for the " + this.props.teamDisplayName + " " + strings.Team} <a href={"/"+this.props.teamName+"/signup/gitlab"}>{"or sign up with GitLab."}</a></p>
|
<p>{"Choose your username and password for the " + this.props.teamDisplayName + " " + strings.Team} <a href={"/"+this.props.teamName+"/signup/gitlab"+window.location.search}>{"or sign up with GitLab."}</a></p>
|
||||||
<p>Your username can be made of lowercase letters and numbers.</p>
|
<p>Your username can be made of lowercase letters and numbers.</p>
|
||||||
<label className="control-label">Username</label>
|
<label className="control-label">Username</label>
|
||||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||||
|
|||||||
56
web/web.go
56
web/web.go
@@ -453,10 +453,48 @@ func resetPassword(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
func signupWithOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
func signupWithOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
params := mux.Vars(r)
|
params := mux.Vars(r)
|
||||||
service := params["service"]
|
service := params["service"]
|
||||||
|
teamName := params["team"]
|
||||||
|
|
||||||
|
if len(teamName) == 0 {
|
||||||
|
c.Err = model.NewAppError("signupWithOAuth", "Invalid team name", "team_name="+teamName)
|
||||||
|
c.Err.StatusCode = http.StatusBadRequest
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := r.URL.Query().Get("h")
|
||||||
|
|
||||||
|
var team *model.Team
|
||||||
|
if result := <-api.Srv.Store.Team().GetByName(teamName); result.Err != nil {
|
||||||
|
c.Err = result.Err
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
team = result.Data.(*model.Team)
|
||||||
|
}
|
||||||
|
|
||||||
|
if api.IsVerifyHashRequired(nil, team, hash) {
|
||||||
|
data := r.URL.Query().Get("d")
|
||||||
|
props := model.MapFromJson(strings.NewReader(data))
|
||||||
|
|
||||||
|
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt)) {
|
||||||
|
c.Err = model.NewAppError("createUser", "The signup link does not appear to be valid", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := strconv.ParseInt(props["time"], 10, 64)
|
||||||
|
if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours
|
||||||
|
c.Err = model.NewAppError("createUser", "The signup link has expired", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if team.Id != props["id"] {
|
||||||
|
c.Err = model.NewAppError("createUser", "Invalid team name", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
redirectUri := c.GetSiteURL() + "/signup/" + service + "/complete"
|
redirectUri := c.GetSiteURL() + "/signup/" + service + "/complete"
|
||||||
|
|
||||||
api.GetAuthorizationCode(c, w, r, service, redirectUri)
|
api.GetAuthorizationCode(c, w, r, teamName, service, redirectUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
func signupCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
func signupCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -522,11 +560,23 @@ func signupCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request)
|
|||||||
func loginWithOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
func loginWithOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
params := mux.Vars(r)
|
params := mux.Vars(r)
|
||||||
service := params["service"]
|
service := params["service"]
|
||||||
l4g.Debug(service)
|
teamName := params["team"]
|
||||||
|
|
||||||
|
if len(teamName) == 0 {
|
||||||
|
c.Err = model.NewAppError("loginWithOAuth", "Invalid team name", "team_name="+teamName)
|
||||||
|
c.Err.StatusCode = http.StatusBadRequest
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure team exists
|
||||||
|
if result := <-api.Srv.Store.Team().GetByName(teamName); result.Err != nil {
|
||||||
|
c.Err = result.Err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
redirectUri := c.GetSiteURL() + "/login/" + service + "/complete"
|
redirectUri := c.GetSiteURL() + "/login/" + service + "/complete"
|
||||||
|
|
||||||
api.GetAuthorizationCode(c, w, r, service, redirectUri)
|
api.GetAuthorizationCode(c, w, r, teamName, service, redirectUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
func loginCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user