Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
3e657357
Commit
3e657357
authored
Sep 28, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'gnet-oauth'
parents
7a650164
e5fc4332
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
237 additions
and
71 deletions
+237
-71
conf/defaults.ini
+27
-21
conf/sample.ini
+10
-1
pkg/api/login.go
+6
-4
pkg/api/login_oauth.go
+5
-4
pkg/models/models.go
+1
-0
pkg/models/user.go
+10
-9
pkg/services/sqlstore/user.go
+5
-1
pkg/setting/setting_oauth.go
+2
-3
pkg/social/grafananet_oauth.go
+114
-0
pkg/social/social.go
+27
-13
public/app/core/controllers/login_ctrl.js
+7
-8
public/app/partials/login.html
+8
-5
public/sass/components/_search.scss
+1
-1
public/sass/pages/_login.scss
+14
-1
No files found.
conf/defaults.ini
View file @
3e657357
...
...
@@ -9,7 +9,7 @@ app_mode = production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
instance_name
=
${HOSTNAME}
#################################### Paths ###############################
#####
#################################### Paths ###############################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
#
...
...
@@ -23,7 +23,7 @@ logs = data/log
#
plugins
=
data/plugins
#################################### Server ##############################
######
#################################### Server ##############################
[server]
# Protocol (http or https)
protocol
=
http
...
...
@@ -57,7 +57,7 @@ enable_gzip = false
cert_file
=
cert_key
=
#################################### Database ############################
########
#################################### Database ############################
[database]
# You can configure the database connection by specifying type, host, name, user and password
# as seperate properties or as on string using the url propertie.
...
...
@@ -84,7 +84,7 @@ server_cert_name =
# For "sqlite3" only, path relative to data_path setting
path
=
grafana.db
#################################### Session #############################
#######
#################################### Session #############################
[session]
# Either "memory", "file", "redis", "mysql", "postgres", "memcache", default is "file"
provider
=
file
...
...
@@ -112,7 +112,7 @@ cookie_secure = false
session_life_time
=
86400
gc_interval_time
=
86400
#################################### Analytics ###########################
#########
#################################### Analytics ###########################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
...
...
@@ -133,7 +133,7 @@ google_analytics_ua_id =
# Google Tag Manager ID, only enabled if you specify an id here
google_tag_manager_id
=
#################################### Security ############################
########
#################################### Security ############################
[security]
# default admin user, created on startup
admin_user
=
admin
...
...
@@ -193,7 +193,7 @@ default_theme = dark
# Allow users to sign in using username and password
allow_user_pass_login
=
true
#################################### Anonymous Auth ######################
####
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
enabled
=
false
...
...
@@ -204,7 +204,7 @@ org_name = Main Org.
# specify role for unauthenticated users
org_role
=
Viewer
#################################### Github Auth #########################
#
#################################### Github Auth #########################
[auth.github]
enabled
=
false
allow_sign_up
=
false
...
...
@@ -217,7 +217,7 @@ api_url = https://api.github.com/user
team_ids
=
allowed_organizations
=
#################################### Google Auth #########################
#
#################################### Google Auth #########################
[auth.google]
enabled
=
false
allow_sign_up
=
false
...
...
@@ -229,7 +229,16 @@ token_url = https://accounts.google.com/o/oauth2/token
api_url
=
https://www.googleapis.com/oauth2/v1/userinfo
allowed_domains
=
#################################### Generic OAuth ##########################
#################################### Grafana.net Auth ####################
[auth.grafananet]
enabled
=
false
allow_sign_up
=
false
client_id
=
some_id
client_secret
=
some_secret
scopes
=
user:email
allowed_organizations
=
#################################### Generic OAuth #######################
[auth.generic_oauth]
enabled
=
false
allow_sign_up
=
false
...
...
@@ -253,12 +262,12 @@ header_name = X-WEBAUTH-USER
header_property
=
username
auto_sign_up
=
true
#################################### Auth LDAP ##########################
#################################### Auth LDAP ##########################
#
[auth.ldap]
enabled
=
false
config_file
=
/etc/grafana/ldap.toml
#################################### SMTP / Emailing #####################
#####
#################################### SMTP / Emailing #####################
[smtp]
enabled
=
false
host
=
localhost:25
...
...
@@ -273,9 +282,6 @@ from_address = admin@grafana.localhost
welcome_email_on_sign_up
=
false
templates_pattern
=
emails/*.html
[tmp.files]
rendered_image_ttl_days
=
14
#################################### Logging ##########################
[log]
# Either "console", "file", "syslog". Default is console and file
...
...
@@ -331,18 +337,18 @@ facility =
tag
=
#################################### AMQP Event Publisher ################
##########
#################################### AMQP Event Publisher ################
[event_publisher]
enabled
=
false
rabbitmq_url
=
amqp://localhost/
exchange
=
grafana_events
#################################### Dashboard JSON files ################
##########
#################################### Dashboard JSON files ################
[dashboards.json]
enabled
=
false
path
=
/var/lib/grafana/dashboards
#################################### Usage Quotas ########################
##
#################################### Usage Quotas ########################
[quota]
enabled
=
false
...
...
@@ -377,7 +383,7 @@ global_api_key = -1
# global limit on number of logged in users.
global_session
=
-1
#################################### Alerting ############################
##########
#################################### Alerting ############################
# docs about alerting can be found in /docs/sources/alerting/
# __.-/|
# \`o_O'
...
...
@@ -396,7 +402,7 @@ global_session = -1
[alerting]
enabled
=
true
#################################### Internal Grafana Metrics ############
##############
#################################### Internal Grafana Metrics ############
# Metrics available at HTTP API Url /api/metrics
[metrics]
enabled
=
true
...
...
@@ -411,7 +417,7 @@ prefix = prod.grafana.%(instance_name)s.
[grafana_net]
url
=
https://grafana.net
#################################### External
image storage ############
##############
#################################### External
Image Storage
##############
[external_image_storage]
# You can choose between (s3, webdav)
provider
=
s3
...
...
conf/sample.ini
View file @
3e657357
...
...
@@ -116,7 +116,7 @@
# in some UI views to notify that grafana or plugin update exists
# This option does not cause any auto updates, nor send any information
# only a GET request to http://grafana.net to get latest versions
check_for_updates
=
true
;
check_for_updates = true
# Google Analytics universal tracking code, only enabled if you specify an id here
;google_analytics_ua_id =
...
...
@@ -224,6 +224,15 @@ check_for_updates = true
;team_ids =
;allowed_organizations =
#################################### Grafana.net Auth ####################
[auth.grafananet]
;enabled = false
;allow_sign_up = false
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =
#################################### Auth Proxy ##########################
[auth.proxy]
;enabled = false
...
...
pkg/api/login.go
View file @
3e657357
...
...
@@ -25,10 +25,12 @@ func LoginView(c *middleware.Context) {
return
}
viewData
.
Settings
[
"googleAuthEnabled"
]
=
setting
.
OAuthService
.
Google
viewData
.
Settings
[
"githubAuthEnabled"
]
=
setting
.
OAuthService
.
GitHub
viewData
.
Settings
[
"genericOAuthEnabled"
]
=
setting
.
OAuthService
.
Generic
viewData
.
Settings
[
"oauthProviderName"
]
=
setting
.
OAuthService
.
OAuthProviderName
enabledOAuths
:=
make
(
map
[
string
]
interface
{})
for
key
,
oauth
:=
range
setting
.
OAuthService
.
OAuthInfos
{
enabledOAuths
[
key
]
=
map
[
string
]
string
{
"name"
:
oauth
.
Name
}
}
viewData
.
Settings
[
"oauth"
]
=
enabledOAuths
viewData
.
Settings
[
"disableUserSignUp"
]
=
!
setting
.
AllowUserSignUp
viewData
.
Settings
[
"loginHint"
]
=
setting
.
LoginHint
viewData
.
Settings
[
"allowUserPassLogin"
]
=
setting
.
AllowUserPassLogin
...
...
pkg/api/login_oauth.go
View file @
3e657357
...
...
@@ -82,10 +82,11 @@ func OAuthLogin(ctx *middleware.Context) {
return
}
cmd
:=
m
.
CreateUserCommand
{
Login
:
userInfo
.
Email
,
Email
:
userInfo
.
Email
,
Name
:
userInfo
.
Name
,
Company
:
userInfo
.
Company
,
Login
:
userInfo
.
Email
,
Email
:
userInfo
.
Email
,
Name
:
userInfo
.
Name
,
Company
:
userInfo
.
Company
,
DefaultOrgRole
:
userInfo
.
Role
,
}
if
err
=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
...
...
pkg/models/models.go
View file @
3e657357
...
...
@@ -7,4 +7,5 @@ const (
GOOGLE
TWITTER
GENERIC
GRAFANANET
)
pkg/models/user.go
View file @
3e657357
...
...
@@ -44,15 +44,16 @@ func (u *User) NameOrFallback() string {
// COMMANDS
type
CreateUserCommand
struct
{
Email
string
Login
string
Name
string
Company
string
OrgName
string
Password
string
EmailVerified
bool
IsAdmin
bool
SkipOrgSetup
bool
Email
string
Login
string
Name
string
Company
string
OrgName
string
Password
string
EmailVerified
bool
IsAdmin
bool
SkipOrgSetup
bool
DefaultOrgRole
string
Result
User
}
...
...
pkg/services/sqlstore/user.go
View file @
3e657357
...
...
@@ -128,7 +128,11 @@ func CreateUser(cmd *m.CreateUserCommand) error {
}
if
setting
.
AutoAssignOrg
&&
!
user
.
IsAdmin
{
orgUser
.
Role
=
m
.
RoleType
(
setting
.
AutoAssignOrgRole
)
if
len
(
cmd
.
DefaultOrgRole
)
>
0
{
orgUser
.
Role
=
m
.
RoleType
(
cmd
.
DefaultOrgRole
)
}
else
{
orgUser
.
Role
=
m
.
RoleType
(
setting
.
AutoAssignOrgRole
)
}
}
if
_
,
err
=
sess
.
Insert
(
&
orgUser
);
err
!=
nil
{
...
...
pkg/setting/setting_oauth.go
View file @
3e657357
...
...
@@ -8,12 +8,11 @@ type OAuthInfo struct {
AllowedDomains
[]
string
ApiUrl
string
AllowSignup
bool
Name
string
}
type
OAuther
struct
{
GitHub
,
Google
,
Twitter
,
Generic
bool
OAuthInfos
map
[
string
]
*
OAuthInfo
OAuthProviderName
string
OAuthInfos
map
[
string
]
*
OAuthInfo
}
var
OAuthService
*
OAuther
pkg/social/grafananet_oauth.go
0 → 100644
View file @
3e657357
package
social
import
(
"encoding/json"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/models"
"golang.org/x/oauth2"
)
type
SocialGrafanaNet
struct
{
*
oauth2
.
Config
url
string
allowedOrganizations
[]
string
allowSignup
bool
}
func
(
s
*
SocialGrafanaNet
)
Type
()
int
{
return
int
(
models
.
GRAFANANET
)
}
func
(
s
*
SocialGrafanaNet
)
IsEmailAllowed
(
email
string
)
bool
{
return
true
}
func
(
s
*
SocialGrafanaNet
)
IsSignupAllowed
()
bool
{
return
s
.
allowSignup
}
func
(
s
*
SocialGrafanaNet
)
IsOrganizationMember
(
client
*
http
.
Client
)
bool
{
if
len
(
s
.
allowedOrganizations
)
==
0
{
return
true
}
organizations
,
err
:=
s
.
FetchOrganizations
(
client
)
if
err
!=
nil
{
return
false
}
for
_
,
allowedOrganization
:=
range
s
.
allowedOrganizations
{
for
_
,
organization
:=
range
organizations
{
if
organization
==
allowedOrganization
{
return
true
}
}
}
return
false
}
func
(
s
*
SocialGrafanaNet
)
FetchOrganizations
(
client
*
http
.
Client
)
([]
string
,
error
)
{
type
Record
struct
{
Login
string
`json:"login"`
}
url
:=
fmt
.
Sprintf
(
s
.
url
+
"/api/oauth2/user/orgs"
)
r
,
err
:=
client
.
Get
(
url
)
if
err
!=
nil
{
return
nil
,
err
}
defer
r
.
Body
.
Close
()
var
records
[]
Record
if
err
=
json
.
NewDecoder
(
r
.
Body
)
.
Decode
(
&
records
);
err
!=
nil
{
return
nil
,
err
}
var
logins
=
make
([]
string
,
len
(
records
))
for
i
,
record
:=
range
records
{
logins
[
i
]
=
record
.
Login
}
return
logins
,
nil
}
func
(
s
*
SocialGrafanaNet
)
UserInfo
(
token
*
oauth2
.
Token
)
(
*
BasicUserInfo
,
error
)
{
var
data
struct
{
Id
int
`json:"id"`
Name
string
`json:"login"`
Email
string
`json:"email"`
Role
string
`json:"role"`
}
var
err
error
client
:=
s
.
Client
(
oauth2
.
NoContext
,
token
)
r
,
err
:=
client
.
Get
(
s
.
url
+
"/api/oauth2/user"
)
if
err
!=
nil
{
return
nil
,
err
}
defer
r
.
Body
.
Close
()
if
err
=
json
.
NewDecoder
(
r
.
Body
)
.
Decode
(
&
data
);
err
!=
nil
{
return
nil
,
err
}
userInfo
:=
&
BasicUserInfo
{
Identity
:
strconv
.
Itoa
(
data
.
Id
),
Name
:
data
.
Name
,
Email
:
data
.
Email
,
Role
:
data
.
Role
,
}
if
!
s
.
IsOrganizationMember
(
client
)
{
return
nil
,
ErrMissingOrganizationMembership
}
return
userInfo
,
nil
}
pkg/social/social.go
View file @
3e657357
...
...
@@ -15,6 +15,7 @@ type BasicUserInfo struct {
Email
string
Login
string
Company
string
Role
string
}
type
SocialConnector
interface
{
...
...
@@ -36,7 +37,7 @@ func NewOAuthService() {
setting
.
OAuthService
=
&
setting
.
OAuther
{}
setting
.
OAuthService
.
OAuthInfos
=
make
(
map
[
string
]
*
setting
.
OAuthInfo
)
allOauthes
:=
[]
string
{
"github"
,
"google"
,
"generic_oauth"
}
allOauthes
:=
[]
string
{
"github"
,
"google"
,
"generic_oauth"
,
"grafananet"
}
for
_
,
name
:=
range
allOauthes
{
sec
:=
setting
.
Cfg
.
Section
(
"auth."
+
name
)
...
...
@@ -50,6 +51,7 @@ func NewOAuthService() {
Enabled
:
sec
.
Key
(
"enabled"
)
.
MustBool
(),
AllowedDomains
:
sec
.
Key
(
"allowed_domains"
)
.
Strings
(
" "
),
AllowSignup
:
sec
.
Key
(
"allow_sign_up"
)
.
MustBool
(),
Name
:
sec
.
Key
(
"name"
)
.
MustString
(
name
),
}
if
!
info
.
Enabled
{
...
...
@@ -70,22 +72,18 @@ func NewOAuthService() {
// GitHub.
if
name
==
"github"
{
setting
.
OAuthService
.
GitHub
=
true
teamIds
:=
sec
.
Key
(
"team_ids"
)
.
Ints
(
","
)
allowedOrganizations
:=
sec
.
Key
(
"allowed_organizations"
)
.
Strings
(
" "
)
SocialMap
[
"github"
]
=
&
SocialGithub
{
Config
:
&
config
,
allowedDomains
:
info
.
AllowedDomains
,
apiUrl
:
info
.
ApiUrl
,
allowSignup
:
info
.
AllowSignup
,
teamIds
:
teamIds
,
allowedOrganizations
:
allowedOrganizations
,
teamIds
:
sec
.
Key
(
"team_ids"
)
.
Ints
(
","
)
,
allowedOrganizations
:
sec
.
Key
(
"allowed_organizations"
)
.
Strings
(
" "
)
,
}
}
// Google.
if
name
==
"google"
{
setting
.
OAuthService
.
Google
=
true
SocialMap
[
"google"
]
=
&
SocialGoogle
{
Config
:
&
config
,
allowedDomains
:
info
.
AllowedDomains
,
apiUrl
:
info
.
ApiUrl
,
...
...
@@ -95,17 +93,33 @@ func NewOAuthService() {
// Generic - Uses the same scheme as Github.
if
name
==
"generic_oauth"
{
setting
.
OAuthService
.
Generic
=
true
setting
.
OAuthService
.
OAuthProviderName
=
sec
.
Key
(
"oauth_provider_name"
)
.
String
()
teamIds
:=
sec
.
Key
(
"team_ids"
)
.
Ints
(
","
)
allowedOrganizations
:=
sec
.
Key
(
"allowed_organizations"
)
.
Strings
(
" "
)
SocialMap
[
"generic_oauth"
]
=
&
GenericOAuth
{
Config
:
&
config
,
allowedDomains
:
info
.
AllowedDomains
,
apiUrl
:
info
.
ApiUrl
,
allowSignup
:
info
.
AllowSignup
,
teamIds
:
teamIds
,
allowedOrganizations
:
allowedOrganizations
,
teamIds
:
sec
.
Key
(
"team_ids"
)
.
Ints
(
","
),
allowedOrganizations
:
sec
.
Key
(
"allowed_organizations"
)
.
Strings
(
" "
),
}
}
if
name
==
"grafananet"
{
config
:=
oauth2
.
Config
{
ClientID
:
info
.
ClientId
,
ClientSecret
:
info
.
ClientSecret
,
Endpoint
:
oauth2
.
Endpoint
{
AuthURL
:
setting
.
GrafanaNetUrl
+
"/oauth2/authorize"
,
TokenURL
:
setting
.
GrafanaNetUrl
+
"/api/oauth2/token"
,
},
RedirectURL
:
strings
.
TrimSuffix
(
setting
.
AppUrl
,
"/"
)
+
SocialBaseUrl
+
name
,
Scopes
:
info
.
Scopes
,
}
SocialMap
[
"grafananet"
]
=
&
SocialGrafanaNet
{
Config
:
&
config
,
url
:
setting
.
GrafanaNetUrl
,
allowSignup
:
info
.
AllowSignup
,
allowedOrganizations
:
sec
.
Key
(
"allowed_organizations"
)
.
Strings
(
" "
),
}
}
}
...
...
public/app/core/controllers/login_ctrl.js
View file @
3e657357
define
([
'angular'
,
'lodash'
,
'../core_module'
,
'app/core/config'
,
],
function
(
angular
,
coreModule
,
config
)
{
function
(
angular
,
_
,
coreModule
,
config
)
{
'use strict'
;
var
failCodes
=
{
"1000"
:
"Required
Github
team membership not fulfilled"
,
"1001"
:
"Required
Github
organization membership not fulfilled"
,
"1000"
:
"Required team membership not fulfilled"
,
"1001"
:
"Required organization membership not fulfilled"
,
"1002"
:
"Required email domain not fulfilled"
,
};
...
...
@@ -21,12 +22,10 @@ function (angular, coreModule, config) {
contextSrv
.
sidemenu
=
false
;
$scope
.
googleAuthEnabled
=
config
.
googleAuthEnabled
;
$scope
.
githubAuthEnabled
=
config
.
githubAuthEnabled
;
$scope
.
oauthEnabled
=
config
.
githubAuthEnabled
||
config
.
googleAuthEnabled
||
config
.
genericOAuthEnabled
;
$scope
.
oauth
=
config
.
oauth
;
$scope
.
oauthEnabled
=
_
.
keys
(
config
.
oauth
).
length
>
0
;
$scope
.
allowUserPassLogin
=
config
.
allowUserPassLogin
;
$scope
.
genericOAuthEnabled
=
config
.
genericOAuthEnabled
;
$scope
.
oauthProviderName
=
config
.
oauthProviderName
;
$scope
.
disableUserSignUp
=
config
.
disableUserSignUp
;
$scope
.
loginHint
=
config
.
loginHint
;
...
...
public/app/partials/login.html
View file @
3e657357
...
...
@@ -51,18 +51,21 @@
<div
class=
"clearfix"
></div>
<div
class=
"login-oauth text-center"
ng-show=
"oauthEnabled"
>
<a
class=
"btn btn-large btn-google"
href=
"login/google"
target=
"_self"
ng-if=
"
googleAuthEnabled
"
>
<a
class=
"btn btn-large btn-google"
href=
"login/google"
target=
"_self"
ng-if=
"
oauth.google
"
>
<i
class=
"fa fa-google"
></i>
with Google
</a>
<a
class=
"btn btn-large btn-github"
href=
"login/github"
target=
"_self"
ng-if=
"
githubAuthEnabled
"
>
<a
class=
"btn btn-large btn-github"
href=
"login/github"
target=
"_self"
ng-if=
"
oauth.github
"
>
<i
class=
"fa fa-github"
></i>
with Github
</a>
<a
class=
"btn btn-large btn-generic-oauth"
href=
"login/generic_oauth"
target=
"_self"
ng-if=
"genericOAuthEnabled"
>
<a
class=
"btn btn-large btn-grafana-net"
href=
"login/grafananet"
target=
"_self"
ng-if=
"oauth.grafananet"
>
with
<span>
Grafana.net
</span>
</a>
<a
class=
"btn btn-large btn-generic-oauth"
href=
"login/generic_oauth"
target=
"_self"
ng-if=
"oauth.generic_oauth"
>
<i
class=
"fa fa-gear"
></i>
with {{oauthProviderName || "OAuth 2"
}}
</a>
with {{oauth.generic_oauth.name
}}
</a>
</div>
</div>
...
...
public/sass/components/_search.scss
View file @
3e657357
...
...
@@ -111,7 +111,7 @@
font-size
:
$font-size-sm
;
padding-right
:
7rem
;
background
:
url(../img/grafana_net_logo.svg)
;
background-size
:
6
.5rem
3rem
;
background-size
:
6
.5rem
;
background-repeat
:
no-repeat
;
background-position
:
right
;
position
:
relative
;
...
...
public/sass/pages/_login.scss
View file @
3e657357
...
...
@@ -112,6 +112,19 @@
background
:
#555
;
color
:
white
;
}
.btn-grafana-net
{
background
:
url(../img/grafana_net_logo.svg)
;
background-size
:
10rem
;
background-repeat
:
no-repeat
;
background-position
:
right
35%
;
overflow
:
hidden
;
padding-right
:
10
.5rem
;
span
{
display
:
none
;
}
}
}
.password-recovery
{
...
...
@@ -157,7 +170,7 @@
.invite-box
{
text-align
:
center
;
border
:
1px
solid
$tight-form-func-bg
;
background-color
:
$panel-bg
;
background-color
:
$panel-bg
;
max-width
:
800px
;
margin-left
:
auto
;
margin-right
:
auto
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment