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
3226a3a5
Commit
3226a3a5
authored
Jan 08, 2015
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed hashing of passwords, Closes #3
parent
6d814af0
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
138 additions
and
60 deletions
+138
-60
grafana
+1
-1
pkg/api/account.go
+2
-2
pkg/api/dashboard.go
+4
-44
pkg/api/dataproxy.go
+3
-3
pkg/api/login.go
+5
-4
pkg/api/register.go
+4
-2
pkg/api/render.go
+2
-2
pkg/api/search.go
+45
-0
pkg/models/account.go
+2
-0
pkg/stores/sqlstore/accounts.go
+1
-0
pkg/util/encoding.go
+67
-0
pkg/util/json.go
+1
-1
pkg/util/url.go
+1
-1
No files found.
grafana
@
164435f7
Subproject commit
d3e11cabd51d082244f83258b02fd635cc780c08
Subproject commit
164435f71d3462fa1719791e1c8eb9841374d299
pkg/api/account.go
View file @
3226a3a5
...
...
@@ -4,7 +4,7 @@ import (
"github.com/torkelo/grafana-pro/pkg/bus"
"github.com/torkelo/grafana-pro/pkg/middleware"
m
"github.com/torkelo/grafana-pro/pkg/models"
"github.com/torkelo/grafana-pro/pkg/util
s
"
"github.com/torkelo/grafana-pro/pkg/util"
)
func
GetAccount
(
c
*
middleware
.
Context
)
{
...
...
@@ -59,7 +59,7 @@ func GetOtherAccounts(c *middleware.Context) {
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
c
.
JSON
(
500
,
util
s
.
DynMap
{
"message"
:
err
.
Error
()})
c
.
JSON
(
500
,
util
.
DynMap
{
"message"
:
err
.
Error
()})
return
}
...
...
pkg/api/dashboard.go
View file @
3226a3a5
package
api
import
(
"regexp"
"strings"
"github.com/torkelo/grafana-pro/pkg/bus"
"github.com/torkelo/grafana-pro/pkg/middleware"
m
"github.com/torkelo/grafana-pro/pkg/models"
"github.com/torkelo/grafana-pro/pkg/util
s
"
"github.com/torkelo/grafana-pro/pkg/util"
)
func
GetDashboard
(
c
*
middleware
.
Context
)
{
...
...
@@ -29,15 +26,13 @@ func DeleteDashboard(c *middleware.Context) {
slug
:=
c
.
Params
(
":slug"
)
query
:=
m
.
GetDashboardQuery
{
Slug
:
slug
,
AccountId
:
c
.
GetAccountId
()}
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
c
.
JsonApiErr
(
404
,
"Dashboard not found"
,
nil
)
return
}
cmd
:=
m
.
DeleteDashboardCommand
{
Slug
:
slug
,
AccountId
:
c
.
GetAccountId
()}
err
=
bus
.
Dispatch
(
&
cmd
)
if
err
!=
nil
{
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Failed to delete dashboard"
,
err
)
return
}
...
...
@@ -47,41 +42,6 @@ func DeleteDashboard(c *middleware.Context) {
c
.
JSON
(
200
,
resp
)
}
func
Search
(
c
*
middleware
.
Context
)
{
queryText
:=
c
.
Query
(
"q"
)
result
:=
m
.
SearchResult
{
Dashboards
:
[]
*
m
.
DashboardSearchHit
{},
Tags
:
[]
*
m
.
DashboardTagCloudItem
{},
}
if
strings
.
HasPrefix
(
queryText
,
"tags!:"
)
{
query
:=
m
.
GetDashboardTagsQuery
{}
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Failed to get tags from database"
,
err
)
return
}
result
.
Tags
=
query
.
Result
result
.
TagsOnly
=
true
}
else
{
searchQueryRegEx
,
_
:=
regexp
.
Compile
(
`(tags:(\w*)\sAND\s)?(?:title:)?(.*)?`
)
matches
:=
searchQueryRegEx
.
FindStringSubmatch
(
queryText
)
query
:=
m
.
SearchDashboardsQuery
{
Title
:
matches
[
3
],
Tag
:
matches
[
2
],
AccountId
:
c
.
GetAccountId
(),
}
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Search failed"
,
err
)
return
}
result
.
Dashboards
=
query
.
Result
}
c
.
JSON
(
200
,
result
)
}
func
PostDashboard
(
c
*
middleware
.
Context
)
{
var
cmd
m
.
SaveDashboardCommand
...
...
@@ -102,5 +62,5 @@ func PostDashboard(c *middleware.Context) {
return
}
c
.
JSON
(
200
,
util
s
.
DynMap
{
"status"
:
"success"
,
"slug"
:
cmd
.
Result
.
Slug
})
c
.
JSON
(
200
,
util
.
DynMap
{
"status"
:
"success"
,
"slug"
:
cmd
.
Result
.
Slug
})
}
pkg/api/dataproxy.go
View file @
3226a3a5
...
...
@@ -8,7 +8,7 @@ import (
"github.com/torkelo/grafana-pro/pkg/bus"
"github.com/torkelo/grafana-pro/pkg/middleware"
m
"github.com/torkelo/grafana-pro/pkg/models"
"github.com/torkelo/grafana-pro/pkg/util
s
"
"github.com/torkelo/grafana-pro/pkg/util"
)
func
NewReverseProxy
(
ds
*
m
.
DataSource
,
proxyPath
string
)
*
httputil
.
ReverseProxy
{
...
...
@@ -21,12 +21,12 @@ func NewReverseProxy(ds *m.DataSource, proxyPath string) *httputil.ReverseProxy
reqQueryVals
:=
req
.
URL
.
Query
()
if
ds
.
Type
==
m
.
DS_INFLUXDB
{
req
.
URL
.
Path
=
util
s
.
JoinUrlFragments
(
target
.
Path
,
"db/"
+
ds
.
Database
+
"/"
+
proxyPath
)
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
target
.
Path
,
"db/"
+
ds
.
Database
+
"/"
+
proxyPath
)
reqQueryVals
.
Add
(
"u"
,
ds
.
User
)
reqQueryVals
.
Add
(
"p"
,
ds
.
Password
)
req
.
URL
.
RawQuery
=
reqQueryVals
.
Encode
()
}
else
{
req
.
URL
.
Path
=
util
s
.
JoinUrlFragments
(
target
.
Path
,
proxyPath
)
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
target
.
Path
,
proxyPath
)
}
}
...
...
pkg/api/login.go
View file @
3226a3a5
...
...
@@ -6,7 +6,7 @@ import (
"github.com/torkelo/grafana-pro/pkg/log"
"github.com/torkelo/grafana-pro/pkg/middleware"
m
"github.com/torkelo/grafana-pro/pkg/models"
"github.com/torkelo/grafana-pro/pkg/util
s
"
"github.com/torkelo/grafana-pro/pkg/util"
)
type
loginJsonModel
struct
{
...
...
@@ -19,7 +19,7 @@ func LoginPost(c *middleware.Context) {
var
loginModel
loginJsonModel
if
!
c
.
JsonBody
(
&
loginModel
)
{
c
.
JSON
(
400
,
util
s
.
DynMap
{
"status
"
:
"bad request"
})
c
.
JSON
(
400
,
util
.
DynMap
{
"message
"
:
"bad request"
})
return
}
...
...
@@ -33,7 +33,8 @@ func LoginPost(c *middleware.Context) {
account
:=
userQuery
.
Result
if
loginModel
.
Password
!=
account
.
Password
{
passwordHashed
:=
util
.
EncodePassword
(
loginModel
.
Password
,
account
.
Salt
)
if
passwordHashed
!=
account
.
Password
{
c
.
JsonApiErr
(
401
,
"Invalid username or password"
,
err
)
return
}
...
...
@@ -57,5 +58,5 @@ func loginUserWithAccount(account *m.Account, c *middleware.Context) {
func
LogoutPost
(
c
*
middleware
.
Context
)
{
c
.
Session
.
Delete
(
"accountId"
)
c
.
JSON
(
200
,
util
s
.
DynMap
{
"status"
:
"logged out"
})
c
.
JSON
(
200
,
util
.
DynMap
{
"status"
:
"logged out"
})
}
pkg/api/register.go
View file @
3226a3a5
...
...
@@ -4,6 +4,7 @@ import (
"github.com/torkelo/grafana-pro/pkg/bus"
"github.com/torkelo/grafana-pro/pkg/middleware"
m
"github.com/torkelo/grafana-pro/pkg/models"
"github.com/torkelo/grafana-pro/pkg/util"
)
func
CreateAccount
(
c
*
middleware
.
Context
)
{
...
...
@@ -15,9 +16,10 @@ func CreateAccount(c *middleware.Context) {
}
cmd
.
Login
=
cmd
.
Email
err
:=
bus
.
Dispatch
(
&
cmd
)
cmd
.
Salt
=
util
.
GetRandomString
(
10
)
cmd
.
Password
=
util
.
EncodePassword
(
cmd
.
Password
,
cmd
.
Salt
)
if
err
!=
nil
{
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"failed to create account"
,
err
)
return
}
...
...
pkg/api/render.go
View file @
3226a3a5
...
...
@@ -6,12 +6,12 @@ import (
"github.com/torkelo/grafana-pro/pkg/components/renderer"
"github.com/torkelo/grafana-pro/pkg/middleware"
"github.com/torkelo/grafana-pro/pkg/util
s
"
"github.com/torkelo/grafana-pro/pkg/util"
)
func
RenderToPng
(
c
*
middleware
.
Context
)
{
accountId
:=
c
.
GetAccountId
()
queryReader
:=
util
s
.
NewUrlQueryReader
(
c
.
Req
.
URL
)
queryReader
:=
util
.
NewUrlQueryReader
(
c
.
Req
.
URL
)
queryParams
:=
"?render&accountId="
+
strconv
.
FormatInt
(
accountId
,
10
)
+
"&"
+
c
.
Req
.
URL
.
RawQuery
renderOpts
:=
&
renderer
.
RenderOpts
{
...
...
pkg/api/search.go
0 → 100644
View file @
3226a3a5
package
api
import
(
"regexp"
"strings"
"github.com/torkelo/grafana-pro/pkg/bus"
"github.com/torkelo/grafana-pro/pkg/middleware"
m
"github.com/torkelo/grafana-pro/pkg/models"
)
func
Search
(
c
*
middleware
.
Context
)
{
queryText
:=
c
.
Query
(
"q"
)
result
:=
m
.
SearchResult
{
Dashboards
:
[]
*
m
.
DashboardSearchHit
{},
Tags
:
[]
*
m
.
DashboardTagCloudItem
{},
}
if
strings
.
HasPrefix
(
queryText
,
"tags!:"
)
{
query
:=
m
.
GetDashboardTagsQuery
{}
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Failed to get tags from database"
,
err
)
return
}
result
.
Tags
=
query
.
Result
result
.
TagsOnly
=
true
}
else
{
searchQueryRegEx
,
_
:=
regexp
.
Compile
(
`(tags:(\w*)\sAND\s)?(?:title:)?(.*)?`
)
matches
:=
searchQueryRegEx
.
FindStringSubmatch
(
queryText
)
query
:=
m
.
SearchDashboardsQuery
{
Title
:
matches
[
3
],
Tag
:
matches
[
2
],
AccountId
:
c
.
GetAccountId
(),
}
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Search failed"
,
err
)
return
}
result
.
Dashboards
=
query
.
Result
}
c
.
JSON
(
200
,
result
)
}
pkg/models/account.go
View file @
3226a3a5
...
...
@@ -18,6 +18,7 @@ type Account struct {
FullName
string
Password
string
IsAdmin
bool
Rands
string
`xorm:"VARCHAR(10)"`
Salt
string
`xorm:"VARCHAR(10)"`
Company
string
NextDashboardId
int
...
...
@@ -55,6 +56,7 @@ type CreateAccountCommand struct {
Password
string
`json:"password" binding:"required"`
Name
string
`json:"name"`
Company
string
`json:"company"`
Salt
string
`json:"-"`
Result
Account
`json:"-"`
}
...
...
pkg/stores/sqlstore/accounts.go
View file @
3226a3a5
...
...
@@ -26,6 +26,7 @@ func CreateAccount(cmd *m.CreateAccountCommand) error {
Email
:
cmd
.
Email
,
Login
:
cmd
.
Login
,
Password
:
cmd
.
Password
,
Salt
:
cmd
.
Salt
,
Created
:
time
.
Now
(),
Updated
:
time
.
Now
(),
}
...
...
pkg/util/encoding.go
0 → 100644
View file @
3226a3a5
package
util
import
(
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"fmt"
"hash"
)
// source: https://github.com/gogits/gogs/blob/9ee80e3e5426821f03a4e99fad34418f5c736413/modules/base/tool.go#L58
func
GetRandomString
(
n
int
,
alphabets
...
byte
)
string
{
const
alphanum
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var
bytes
=
make
([]
byte
,
n
)
rand
.
Read
(
bytes
)
for
i
,
b
:=
range
bytes
{
if
len
(
alphabets
)
==
0
{
bytes
[
i
]
=
alphanum
[
b
%
byte
(
len
(
alphanum
))]
}
else
{
bytes
[
i
]
=
alphabets
[
b
%
byte
(
len
(
alphabets
))]
}
}
return
string
(
bytes
)
}
func
EncodePassword
(
password
string
,
salt
string
)
string
{
newPasswd
:=
PBKDF2
([]
byte
(
password
),
[]
byte
(
salt
),
10000
,
50
,
sha256
.
New
)
return
fmt
.
Sprintf
(
"%x"
,
newPasswd
)
}
// http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto
func
PBKDF2
(
password
,
salt
[]
byte
,
iter
,
keyLen
int
,
h
func
()
hash
.
Hash
)
[]
byte
{
prf
:=
hmac
.
New
(
h
,
password
)
hashLen
:=
prf
.
Size
()
numBlocks
:=
(
keyLen
+
hashLen
-
1
)
/
hashLen
var
buf
[
4
]
byte
dk
:=
make
([]
byte
,
0
,
numBlocks
*
hashLen
)
U
:=
make
([]
byte
,
hashLen
)
for
block
:=
1
;
block
<=
numBlocks
;
block
++
{
// N.B.: || means concatenation, ^ means XOR
// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
// U_1 = PRF(password, salt || uint(i))
prf
.
Reset
()
prf
.
Write
(
salt
)
buf
[
0
]
=
byte
(
block
>>
24
)
buf
[
1
]
=
byte
(
block
>>
16
)
buf
[
2
]
=
byte
(
block
>>
8
)
buf
[
3
]
=
byte
(
block
)
prf
.
Write
(
buf
[
:
4
])
dk
=
prf
.
Sum
(
dk
)
T
:=
dk
[
len
(
dk
)
-
hashLen
:
]
copy
(
U
,
T
)
// U_n = PRF(password, U_(n-1))
for
n
:=
2
;
n
<=
iter
;
n
++
{
prf
.
Reset
()
prf
.
Write
(
U
)
U
=
U
[
:
0
]
U
=
prf
.
Sum
(
U
)
for
x
:=
range
U
{
T
[
x
]
^=
U
[
x
]
}
}
}
return
dk
[
:
keyLen
]
}
pkg/util
s
/json.go
→
pkg/util/json.go
View file @
3226a3a5
package
util
s
package
util
type
DynMap
map
[
string
]
interface
{}
pkg/util
s
/url.go
→
pkg/util/url.go
View file @
3226a3a5
package
util
s
package
util
import
(
"net/url"
...
...
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