Add common type for oauth authorization errors

pull/7426/head
Alexander Menzhinsky 9 years ago
parent aef4195493
commit 30c334a2b8
No known key found for this signature in database
GPG Key ID: B02024EEE2EF7B9E
  1. 5
      pkg/api/login.go
  2. 30
      pkg/api/login_oauth.go
  3. 8
      pkg/social/github_oauth.go
  4. 8
      pkg/social/social.go
  5. 14
      public/app/core/controllers/login_ctrl.js

@ -35,6 +35,11 @@ func LoginView(c *middleware.Context) {
viewData.Settings["loginHint"] = setting.LoginHint viewData.Settings["loginHint"] = setting.LoginHint
viewData.Settings["disableLoginForm"] = setting.DisableLoginForm viewData.Settings["disableLoginForm"] = setting.DisableLoginForm
if loginError, ok := c.Session.Get("loginError").(string); ok {
c.Session.Set("loginError", "") // TODO: is there a proper way to delete a session var?
viewData.Settings["loginError"] = loginError
}
if !tryLoginUsingRememberCookie(c) { if !tryLoginUsingRememberCookie(c) {
c.HTML(200, VIEW_INDEX, viewData) c.HTML(200, VIEW_INDEX, viewData)
return return

@ -22,6 +22,13 @@ import (
"github.com/grafana/grafana/pkg/social" "github.com/grafana/grafana/pkg/social"
) )
var (
ErrProviderDeniedRequest = errors.New("Login provider denied login request")
ErrEmailNotAllowed = errors.New("Required email domain not fulfilled")
ErrSignUpNotAllowed = errors.New("Signup is not allowed for this adapter")
ErrUsersQuotaReached = errors.New("Users quota reached")
)
func GenStateString() string { func GenStateString() string {
rnd := make([]byte, 32) rnd := make([]byte, 32)
rand.Read(rnd) rand.Read(rnd)
@ -44,8 +51,7 @@ func OAuthLogin(ctx *middleware.Context) {
error := ctx.Query("error") error := ctx.Query("error")
if error != "" { if error != "" {
errorDesc := ctx.Query("error_description") errorDesc := ctx.Query("error_description")
ctx.Logger.Info("OAuthLogin Failed", "error", error, "errorDesc", errorDesc) redirectWithError(ctx, ErrProviderDeniedRequest, "error", error, "errorDesc", errorDesc)
ctx.Redirect(setting.AppSubUrl + "/login?failCode=1003")
return return
} }
@ -117,10 +123,8 @@ func OAuthLogin(ctx *middleware.Context) {
// get user info // get user info
userInfo, err := connect.UserInfo(client) userInfo, err := connect.UserInfo(client)
if err != nil { if err != nil {
if err == social.ErrMissingTeamMembership { if sErr, ok := err.(*social.Error); ok {
ctx.Redirect(setting.AppSubUrl + "/login?failCode=1000") redirectWithError(ctx, sErr)
} else if err == social.ErrMissingOrganizationMembership {
ctx.Redirect(setting.AppSubUrl + "/login?failCode=1001")
} else { } else {
ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err) ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err)
} }
@ -131,8 +135,7 @@ func OAuthLogin(ctx *middleware.Context) {
// validate that the email is allowed to login to grafana // validate that the email is allowed to login to grafana
if !connect.IsEmailAllowed(userInfo.Email) { if !connect.IsEmailAllowed(userInfo.Email) {
ctx.Logger.Info("OAuth login attempt with unallowed email", "email", userInfo.Email) redirectWithError(ctx, ErrEmailNotAllowed)
ctx.Redirect(setting.AppSubUrl + "/login?failCode=1002")
return return
} }
@ -142,7 +145,7 @@ func OAuthLogin(ctx *middleware.Context) {
// create account if missing // create account if missing
if err == m.ErrUserNotFound { if err == m.ErrUserNotFound {
if !connect.IsSignupAllowed() { if !connect.IsSignupAllowed() {
ctx.Redirect(setting.AppSubUrl + "/login") redirectWithError(ctx, ErrSignUpNotAllowed)
return return
} }
limitReached, err := middleware.QuotaReached(ctx, "user") limitReached, err := middleware.QuotaReached(ctx, "user")
@ -151,7 +154,7 @@ func OAuthLogin(ctx *middleware.Context) {
return return
} }
if limitReached { if limitReached {
ctx.Redirect(setting.AppSubUrl + "/login") redirectWithError(ctx, ErrUsersQuotaReached)
return return
} }
cmd := m.CreateUserCommand{ cmd := m.CreateUserCommand{
@ -179,3 +182,10 @@ func OAuthLogin(ctx *middleware.Context) {
ctx.Redirect(setting.AppSubUrl + "/") ctx.Redirect(setting.AppSubUrl + "/")
} }
func redirectWithError(ctx *middleware.Context, err error, v ...interface{}) {
ctx.Logger.Info(err.Error(), v...)
// TODO: we can use the flash storage here once it's implemented
ctx.Session.Set("loginError", err.Error())
ctx.Redirect(setting.AppSubUrl + "/login")
}

@ -2,7 +2,6 @@ package social
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net/http" "net/http"
@ -21,11 +20,8 @@ type SocialGithub struct {
} }
var ( var (
ErrMissingTeamMembership = errors.New("User not a member of one of the required teams") ErrMissingTeamMembership = &Error{"User not a member of one of the required teams"}
) ErrMissingOrganizationMembership = &Error{"User not a member of one of the required organizations"}
var (
ErrMissingOrganizationMembership = errors.New("User not a member of one of the required organizations")
) )
func (s *SocialGithub) Type() int { func (s *SocialGithub) Type() int {

@ -29,6 +29,14 @@ type SocialConnector interface {
Client(ctx context.Context, t *oauth2.Token) *http.Client Client(ctx context.Context, t *oauth2.Token) *http.Client
} }
type Error struct {
s string
}
func (e *Error) Error() string {
return e.s
}
var ( var (
SocialBaseUrl = "/login/" SocialBaseUrl = "/login/"
SocialMap = make(map[string]SocialConnector) SocialMap = make(map[string]SocialConnector)

@ -7,13 +7,6 @@ define([
function (angular, _, coreModule, config) { function (angular, _, coreModule, config) {
'use strict'; 'use strict';
var failCodes = {
"1000": "Required team membership not fulfilled",
"1001": "Required organization membership not fulfilled",
"1002": "Required email domain not fulfilled",
"1003": "Login provider denied login request",
};
coreModule.default.controller('LoginCtrl', function($scope, backendSrv, contextSrv, $location) { coreModule.default.controller('LoginCtrl', function($scope, backendSrv, contextSrv, $location) {
$scope.formModel = { $scope.formModel = {
user: '', user: '',
@ -36,11 +29,8 @@ function (angular, _, coreModule, config) {
$scope.init = function() { $scope.init = function() {
$scope.$watch("loginMode", $scope.loginModeChanged); $scope.$watch("loginMode", $scope.loginModeChanged);
var params = $location.search(); if (config.loginError) {
if (params.failCode) { $scope.appEvent('alert-warning', ['Login Failed', config.loginError]);
$scope.appEvent('alert-warning', ['Login Failed', failCodes[params.failCode]]);
delete params.failedMsg;
$location.search(params);
} }
}; };

Loading…
Cancel
Save