Forráskód Böngészése

Merge branch 'master' of github.com:grafana/grafana

Torkel Ödegaard 7 éve
szülő
commit
267b96cb48

+ 1 - 0
conf/defaults.ini

@@ -321,6 +321,7 @@ allow_sign_up = true
 client_id = some_id
 client_id = some_id
 client_secret = some_secret
 client_secret = some_secret
 scopes = user:email
 scopes = user:email
+email_attribute_name = email:primary
 auth_url =
 auth_url =
 token_url =
 token_url =
 api_url =
 api_url =

+ 8 - 1
docs/sources/auth/generic-oauth.md

@@ -32,7 +32,14 @@ allowed_domains = mycompany.com mycompany.org
 allow_sign_up = true
 allow_sign_up = true
 ```
 ```
 
 
-Set api_url to the resource that returns [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo) compatible information.
+Set `api_url` to the resource that returns [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo) compatible information.
+
+Grafana will attempt to determine the user's e-mail address by querying the OAuth provider as described below in the following order until an e-mail address is found:
+
+1. Check for the presence of an e-mail address via the `email` field encoded in the OAuth `id_token` parameter.
+2. Check for the presence of an e-mail address in the `attributes` map encoded in the OAuth `id_token` parameter. By default Grafana will perform a lookup into the attributes map using the `email:primary` key, however, this is configurable and can be adjusted by using the `email_attribute_name` configuration option.
+3. Query the `/emails` endpoint of the OAuth provider's API (configured with `api_url`) and check for the presence of an e-mail address marked as a primary address.
+4. If no e-mail address is found in steps (1-3), then the e-mail address of the user is set to the empty string.
 
 
 ## Set up OAuth2 with Okta
 ## Set up OAuth2 with Okta
 
 

+ 2 - 0
docs/sources/features/datasources/mssql.md

@@ -174,6 +174,8 @@ The resulting table panel:
 If you set `Format as` to `Time series`, for use in Graph panel for example, then the query must must have a column named `time` that returns either a sql datetime or any numeric datatype representing unix epoch in seconds. You may return a column named `metric` that is used as metric name for the value column. Any column except `time` and `metric` is treated as a value column. If you omit the `metric` column, the name of the value column will be the metric name. You may select multiple value columns, each will have its name as metric.
 If you set `Format as` to `Time series`, for use in Graph panel for example, then the query must must have a column named `time` that returns either a sql datetime or any numeric datatype representing unix epoch in seconds. You may return a column named `metric` that is used as metric name for the value column. Any column except `time` and `metric` is treated as a value column. If you omit the `metric` column, the name of the value column will be the metric name. You may select multiple value columns, each will have its name as metric.
 If you return multiple value columns and a column named `metric` then this column is used as prefix for the series name (only available in Grafana 5.3+).
 If you return multiple value columns and a column named `metric` then this column is used as prefix for the series name (only available in Grafana 5.3+).
 
 
+Resultsets of time series queries need to be sorted by time.
+
 **Example database table:**
 **Example database table:**
 
 
 ```sql
 ```sql

+ 2 - 0
docs/sources/features/datasources/mysql.md

@@ -129,6 +129,8 @@ Any column except `time` and `metric` is treated as a value column.
 You may return a column named `metric` that is used as metric name for the value column.
 You may return a column named `metric` that is used as metric name for the value column.
 If you return multiple value columns and a column named `metric` then this column is used as prefix for the series name (only available in Grafana 5.3+).
 If you return multiple value columns and a column named `metric` then this column is used as prefix for the series name (only available in Grafana 5.3+).
 
 
+Resultsets of time series queries need to be sorted by time.
+
 **Example with `metric` column:**
 **Example with `metric` column:**
 
 
 ```sql
 ```sql

+ 2 - 0
docs/sources/features/datasources/postgres.md

@@ -129,6 +129,8 @@ Any column except `time` and `metric` is treated as a value column.
 You may return a column named `metric` that is used as metric name for the value column.
 You may return a column named `metric` that is used as metric name for the value column.
 If you return multiple value columns and a column named `metric` then this column is used as prefix for the series name (only available in Grafana 5.3+).
 If you return multiple value columns and a column named `metric` then this column is used as prefix for the series name (only available in Grafana 5.3+).
 
 
+Resultsets of time series queries need to be sorted by time.
+
 **Example with `metric` column:**
 **Example with `metric` column:**
 
 
 ```sql
 ```sql

+ 1 - 0
pkg/setting/setting_oauth.go

@@ -5,6 +5,7 @@ type OAuthInfo struct {
 	Scopes                 []string
 	Scopes                 []string
 	AuthUrl, TokenUrl      string
 	AuthUrl, TokenUrl      string
 	Enabled                bool
 	Enabled                bool
+	EmailAttributeName     string
 	AllowedDomains         []string
 	AllowedDomains         []string
 	HostedDomain           string
 	HostedDomain           string
 	ApiUrl                 string
 	ApiUrl                 string

+ 4 - 2
pkg/social/generic_oauth.go

@@ -20,6 +20,7 @@ type SocialGenericOAuth struct {
 	allowedOrganizations []string
 	allowedOrganizations []string
 	apiUrl               string
 	apiUrl               string
 	allowSignup          bool
 	allowSignup          bool
+	emailAttributeName   string
 	teamIds              []int
 	teamIds              []int
 }
 }
 
 
@@ -264,8 +265,9 @@ func (s *SocialGenericOAuth) extractEmail(data *UserInfoJson) string {
 		return data.Email
 		return data.Email
 	}
 	}
 
 
-	if data.Attributes["email:primary"] != nil {
-		return data.Attributes["email:primary"][0]
+	emails, ok := data.Attributes[s.emailAttributeName]
+	if ok && len(emails) != 0 {
+		return emails[0]
 	}
 	}
 
 
 	if data.Upn != "" {
 	if data.Upn != "" {

+ 17 - 15
pkg/social/social.go

@@ -60,21 +60,22 @@ func NewOAuthService() {
 	for _, name := range allOauthes {
 	for _, name := range allOauthes {
 		sec := setting.Raw.Section("auth." + name)
 		sec := setting.Raw.Section("auth." + name)
 		info := &setting.OAuthInfo{
 		info := &setting.OAuthInfo{
-			ClientId:       sec.Key("client_id").String(),
-			ClientSecret:   sec.Key("client_secret").String(),
-			Scopes:         util.SplitString(sec.Key("scopes").String()),
-			AuthUrl:        sec.Key("auth_url").String(),
-			TokenUrl:       sec.Key("token_url").String(),
-			ApiUrl:         sec.Key("api_url").String(),
-			Enabled:        sec.Key("enabled").MustBool(),
-			AllowedDomains: util.SplitString(sec.Key("allowed_domains").String()),
-			HostedDomain:   sec.Key("hosted_domain").String(),
-			AllowSignup:    sec.Key("allow_sign_up").MustBool(),
-			Name:           sec.Key("name").MustString(name),
-			TlsClientCert:  sec.Key("tls_client_cert").String(),
-			TlsClientKey:   sec.Key("tls_client_key").String(),
-			TlsClientCa:    sec.Key("tls_client_ca").String(),
-			TlsSkipVerify:  sec.Key("tls_skip_verify_insecure").MustBool(),
+			ClientId:           sec.Key("client_id").String(),
+			ClientSecret:       sec.Key("client_secret").String(),
+			Scopes:             util.SplitString(sec.Key("scopes").String()),
+			AuthUrl:            sec.Key("auth_url").String(),
+			TokenUrl:           sec.Key("token_url").String(),
+			ApiUrl:             sec.Key("api_url").String(),
+			Enabled:            sec.Key("enabled").MustBool(),
+			EmailAttributeName: sec.Key("email_attribute_name").String(),
+			AllowedDomains:     util.SplitString(sec.Key("allowed_domains").String()),
+			HostedDomain:       sec.Key("hosted_domain").String(),
+			AllowSignup:        sec.Key("allow_sign_up").MustBool(),
+			Name:               sec.Key("name").MustString(name),
+			TlsClientCert:      sec.Key("tls_client_cert").String(),
+			TlsClientKey:       sec.Key("tls_client_key").String(),
+			TlsClientCa:        sec.Key("tls_client_ca").String(),
+			TlsSkipVerify:      sec.Key("tls_skip_verify_insecure").MustBool(),
 		}
 		}
 
 
 		if !info.Enabled {
 		if !info.Enabled {
@@ -153,6 +154,7 @@ func NewOAuthService() {
 				allowedDomains:       info.AllowedDomains,
 				allowedDomains:       info.AllowedDomains,
 				apiUrl:               info.ApiUrl,
 				apiUrl:               info.ApiUrl,
 				allowSignup:          info.AllowSignup,
 				allowSignup:          info.AllowSignup,
+				emailAttributeName:   info.EmailAttributeName,
 				teamIds:              sec.Key("team_ids").Ints(","),
 				teamIds:              sec.Key("team_ids").Ints(","),
 				allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()),
 				allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()),
 			}
 			}

+ 2 - 0
public/app/plugins/datasource/mssql/partials/query.editor.html

@@ -45,6 +45,8 @@ Optional:
   - If multiple value columns are returned the metric column is used as prefix.
   - If multiple value columns are returned the metric column is used as prefix.
   - If no column named metric is found the column name of the value column is used as series name
   - If no column named metric is found the column name of the value column is used as series name
 
 
+Resultsets of time series queries need to be sorted by time.
+
 Table:
 Table:
 - return any set of columns
 - return any set of columns
 
 

+ 2 - 0
public/app/plugins/datasource/mysql/partials/query.editor.html

@@ -45,6 +45,8 @@ Optional:
   - If multiple value columns are returned the metric column is used as prefix.
   - If multiple value columns are returned the metric column is used as prefix.
   - If no column named metric is found the column name of the value column is used as series name
   - If no column named metric is found the column name of the value column is used as series name
 
 
+Resultsets of time series queries need to be sorted by time.
+
 Table:
 Table:
 - return any set of columns
 - return any set of columns
 
 

+ 2 - 0
public/app/plugins/datasource/postgres/partials/query.editor.html

@@ -143,6 +143,8 @@ Optional:
   - If multiple value columns are returned the metric column is used as prefix. 
   - If multiple value columns are returned the metric column is used as prefix. 
   - If no column named metric is found the column name of the value column is used as series name
   - If no column named metric is found the column name of the value column is used as series name
 
 
+Resultsets of time series queries need to be sorted by time.
+
 Table:
 Table:
 - return any set of columns
 - return any set of columns