Merge pull request #7426 from Altoros/altoros/authorization-errors
Add common type for oauth authorization errors
This commit is contained in:
@@ -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
|
||||||
|
|||||||
+20
-10
@@ -23,6 +23,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)
|
||||||
@@ -45,8 +52,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +124,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)
|
||||||
}
|
}
|
||||||
@@ -132,8 +136,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +146,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")
|
||||||
@@ -152,7 +155,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{
|
||||||
@@ -186,3 +189,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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user