2014-12-29 06:36:08 -06:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2015-04-29 03:08:01 -05:00
|
|
|
"net/url"
|
2014-12-29 06:36:08 -06:00
|
|
|
|
2014-12-30 03:10:13 -06:00
|
|
|
"golang.org/x/oauth2"
|
|
|
|
|
2015-02-05 03:37:13 -06:00
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
|
|
"github.com/grafana/grafana/pkg/log"
|
2015-03-22 14:14:00 -05:00
|
|
|
"github.com/grafana/grafana/pkg/metrics"
|
2015-02-05 03:37:13 -06:00
|
|
|
"github.com/grafana/grafana/pkg/middleware"
|
|
|
|
m "github.com/grafana/grafana/pkg/models"
|
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
|
|
"github.com/grafana/grafana/pkg/social"
|
2014-12-29 06:36:08 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
func OAuthLogin(ctx *middleware.Context) {
|
|
|
|
if setting.OAuthService == nil {
|
|
|
|
ctx.Handle(404, "login.OAuthLogin(oauth service not enabled)", nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
name := ctx.Params(":name")
|
|
|
|
connect, ok := social.SocialMap[name]
|
|
|
|
if !ok {
|
|
|
|
ctx.Handle(404, "login.OAuthLogin(social login not enabled)", errors.New(name))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
code := ctx.Query("code")
|
|
|
|
if code == "" {
|
2014-12-30 03:10:13 -06:00
|
|
|
ctx.Redirect(connect.AuthCodeURL("", oauth2.AccessTypeOnline))
|
2014-12-29 06:36:08 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle call back
|
2014-12-30 03:10:13 -06:00
|
|
|
token, err := connect.Exchange(oauth2.NoContext, code)
|
2014-12-29 06:36:08 -06:00
|
|
|
if err != nil {
|
|
|
|
ctx.Handle(500, "login.OAuthLogin(NewTransportWithCode)", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Trace("login.OAuthLogin(Got token)")
|
|
|
|
|
2014-12-30 03:10:13 -06:00
|
|
|
userInfo, err := connect.UserInfo(token)
|
2014-12-29 06:36:08 -06:00
|
|
|
if err != nil {
|
2015-04-28 22:22:45 -05:00
|
|
|
if err == social.ErrMissingTeamMembership {
|
2015-04-29 03:08:01 -05:00
|
|
|
ctx.Redirect(setting.AppSubUrl + "/login?failedMsg=" + url.QueryEscape("Required Github team membership not fulfilled"))
|
2015-04-28 22:22:45 -05:00
|
|
|
} else {
|
|
|
|
ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err)
|
|
|
|
}
|
2014-12-29 06:36:08 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-06 07:16:22 -05:00
|
|
|
log.Trace("login.OAuthLogin(social login): %s", userInfo)
|
|
|
|
|
|
|
|
// validate that the email is allowed to login to grafana
|
|
|
|
if !connect.IsEmailAllowed(userInfo.Email) {
|
|
|
|
log.Info("OAuth login attempt with unallowed email, %s", userInfo.Email)
|
2015-04-29 03:08:01 -05:00
|
|
|
ctx.Redirect(setting.AppSubUrl + "/login?failedMsg=" + url.QueryEscape("Required email domain not fulfilled"))
|
2015-04-06 07:16:22 -05:00
|
|
|
return
|
|
|
|
}
|
2014-12-29 06:36:08 -06:00
|
|
|
|
2015-01-19 11:01:04 -06:00
|
|
|
userQuery := m.GetUserByLoginQuery{LoginOrEmail: userInfo.Email}
|
2014-12-29 06:36:08 -06:00
|
|
|
err = bus.Dispatch(&userQuery)
|
|
|
|
|
|
|
|
// create account if missing
|
2015-01-19 11:01:04 -06:00
|
|
|
if err == m.ErrUserNotFound {
|
2015-04-09 20:15:19 -05:00
|
|
|
if !connect.IsSignupAllowed() {
|
2015-01-29 08:46:54 -06:00
|
|
|
ctx.Redirect(setting.AppSubUrl + "/login")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-01-19 11:01:04 -06:00
|
|
|
cmd := m.CreateUserCommand{
|
2014-12-29 06:36:08 -06:00
|
|
|
Login: userInfo.Email,
|
|
|
|
Email: userInfo.Email,
|
|
|
|
Name: userInfo.Name,
|
|
|
|
Company: userInfo.Company,
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = bus.Dispatch(&cmd); err != nil {
|
|
|
|
ctx.Handle(500, "Failed to create account", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
userQuery.Result = &cmd.Result
|
|
|
|
} else if err != nil {
|
|
|
|
ctx.Handle(500, "Unexpected error", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// login
|
2015-01-19 11:01:04 -06:00
|
|
|
loginUserWithUser(userQuery.Result, ctx)
|
2014-12-29 06:36:08 -06:00
|
|
|
|
2015-03-22 14:14:00 -05:00
|
|
|
metrics.M_Api_Login_OAuth.Inc(1)
|
|
|
|
|
2015-01-05 01:21:52 -06:00
|
|
|
ctx.Redirect(setting.AppSubUrl + "/")
|
2014-12-29 06:36:08 -06:00
|
|
|
}
|