Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
145
Issues
145
List
Board
Labels
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-gargantext
Commits
a2dc9494
Commit
a2dc9494
authored
Oct 01, 2019
by
Nicolas Pouillard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Secure API part 3: define a withAccess combinator and use it at most places
parent
87d274b8
Pipeline
#584
failed with stage
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
57 additions
and
38 deletions
+57
-38
API.hs
src/Gargantext/API.hs
+26
-19
Auth.hs
src/Gargantext/API/Auth.hs
+27
-9
Node.hs
src/Gargantext/API/Node.hs
+4
-10
No files found.
src/Gargantext/API.hs
View file @
a2dc9494
...
...
@@ -71,7 +71,7 @@ import Text.Blaze.Html (Html)
--import Gargantext.API.Swagger
--import Gargantext.Database.Node.Contact (HyperdataContact)
import
Gargantext.API.Auth
(
AuthRequest
,
AuthResponse
,
AuthenticatedUser
(
..
),
AuthContext
,
auth
)
import
Gargantext.API.Auth
(
AuthRequest
,
AuthResponse
,
AuthenticatedUser
(
..
),
AuthContext
,
auth
,
withAccess
)
import
Gargantext.API.Count
(
CountAPI
,
count
,
Query
)
import
Gargantext.API.FrontEnd
(
FrontEndAPI
,
frontEndServer
)
import
Gargantext.API.Ngrams
(
HasRepo
(
..
),
HasRepoSaver
(
..
),
saveRepo
,
TableNgramsApi
,
apiNgramsTableDoc
)
...
...
@@ -221,10 +221,15 @@ type GargAPI' =
type
GargPrivateAPI
=
SA
.
Auth
'[
S
A
.
JWT
]
AuthenticatedUser
:>
GargPrivateAPI'
type
Garg
PrivateAPI'
=
-- Roots endpoint
"user"
:>
Summary
"First user endpoint"
type
Garg
AdminAPI
-- Roots endpoint
=
"user"
:>
Summary
"First user endpoint"
:>
Roots
:<|>
"nodes"
:>
Summary
"Nodes endpoint"
:>
ReqBody
'[
J
SON
]
[
NodeId
]
:>
NodesAPI
type
GargPrivateAPI'
=
GargAdminAPI
-- Node endpoint
:<|>
"node"
:>
Summary
"Node endpoint"
...
...
@@ -241,16 +246,12 @@ type GargPrivateAPI' =
-- Document endpoint
:<|>
"document"
:>
Summary
"Document endpoint"
:>
Capture
"id"
DocId
:>
"ngrams"
:>
TableNgramsApi
-- Corpus endpoint
:<|>
"nodes"
:>
Summary
"Nodes endpoint"
:>
ReqBody
'[
J
SON
]
[
NodeId
]
:>
NodesAPI
-- :<|> "counts" :> Stream GET NewLineFraming '[JSON] Count :> CountAPI
-- Corpus endpoint
-- TODO-SECURITY
:<|>
"count"
:>
Summary
"Count endpoint"
:>
ReqBody
'[
J
SON
]
Query
:>
CountAPI
-- Corpus endpoint --> TODO rename s/search/filter/g
:<|>
"search"
:>
Capture
"corpus"
NodeId
:>
SearchPairsAPI
...
...
@@ -308,20 +309,26 @@ serverPrivateGargAPI (Authenticated auser) = serverPrivateGargAPI' auser
serverPrivateGargAPI
_
=
throwAll'
(
_ServerError
#
err401
)
-- Here throwAll' requires a concrete type for the monad.
-- TODO-SECURITY admin only: withAdmin
-- Question: How do we mark admins?
serverGargAdminAPI
::
GargServer
GargAdminAPI
serverGargAdminAPI
=
roots
:<|>
nodesAPI
serverPrivateGargAPI'
::
AuthenticatedUser
->
GargServer
GargPrivateAPI'
serverPrivateGargAPI'
(
AuthenticatedUser
(
NodeId
uid
))
=
roots
=
serverGargAdminAPI
:<|>
nodeAPI
(
Proxy
::
Proxy
HyperdataAny
)
uid
:<|>
nodeAPI
(
Proxy
::
Proxy
HyperdataCorpus
)
uid
:<|>
nodeAPI
(
Proxy
::
Proxy
HyperdataAnnuaire
)
uid
:<|>
apiNgramsTableDoc
:<|>
nodesAPI
:<|>
withAccess
(
Proxy
::
Proxy
TableNgramsApi
)
Proxy
uid
<*>
apiNgramsTableDoc
:<|>
count
-- TODO: undefined
:<|>
searchPairs
-- TODO: move elsewhere
:<|>
graphAPI
-- TODO: mock
:<|>
treeAPI
:<|>
New
.
api
:<|>
New
.
info
uid
:<|>
withAccess
(
Proxy
::
Proxy
SearchPairsAPI
)
Proxy
uid
<*>
searchPairs
-- TODO: move elsewhere
:<|>
withAccess
(
Proxy
::
Proxy
GraphAPI
)
Proxy
uid
<*>
graphAPI
-- TODO: mock
:<|>
withAccess
(
Proxy
::
Proxy
TreeAPI
)
Proxy
uid
<*>
treeAPI
:<|>
New
.
api
-- TODO-SECURITY
:<|>
New
.
info
uid
-- TODO-SECURITY
serverStatic
::
Server
(
Get
'[
H
TML
]
Html
)
serverStatic
=
$
(
do
...
...
src/Gargantext/API/Auth.hs
View file @
a2dc9494
...
...
@@ -20,12 +20,14 @@ TODO-ACCESS Critical
-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module
Gargantext.API.Auth
where
...
...
@@ -39,13 +41,15 @@ import Data.Text (Text, reverse)
import
Data.Text.Lazy
(
toStrict
)
import
Data.Text.Lazy.Encoding
(
decodeUtf8
)
import
GHC.Generics
(
Generic
)
import
Servant
import
Servant.Auth.Server
import
Gargantext.Core.Utils.Prefix
(
unPrefix
,
unPrefixSwagger
)
import
Gargantext.API.Settings
import
Gargantext.API.Types
(
HasJoseError
(
..
),
joseError
)
import
Gargantext.API.Types
(
HasJoseError
(
..
),
joseError
,
HasServerError
,
serverError
,
GargServerC
)
import
Gargantext.Database.Root
(
getRoot
)
import
Gargantext.Database.Types.Node
(
NodePoly
(
_node_id
),
NodeId
)
import
Gargantext.Database.Utils
(
Cmd
'
,
HasConnection
)
import
Gargantext.Database.Tree
(
isDescendantOf
)
import
Gargantext.Database.Types.Node
(
NodePoly
(
_node_id
),
NodeId
(
..
),
UserId
)
import
Gargantext.Database.Utils
(
Cmd
'
,
CmdM
,
HasConnection
)
import
Gargantext.Prelude
hiding
(
reverse
)
import
Test.QuickCheck
(
elements
,
oneof
)
import
Test.QuickCheck.Arbitrary
(
Arbitrary
,
arbitrary
)
...
...
@@ -175,3 +179,17 @@ instance Arbitrary AuthValid where
,
tr
<-
[
1
..
3
]
]
withAccessM
::
(
CmdM
env
err
m
,
HasServerError
err
)
=>
UserId
->
NodeId
->
m
a
->
m
a
withAccessM
uId
id
m
=
do
d
<-
id
`
isDescendantOf
`
NodeId
uId
if
d
then
m
else
serverError
err401
withAccess
::
forall
env
err
m
api
.
(
GargServerC
env
err
m
,
HasServer
api
'[
]
)
=>
Proxy
api
->
Proxy
m
->
UserId
->
NodeId
->
ServerT
api
m
->
ServerT
api
m
withAccess
p
_
uId
id
=
hoistServer
p
f
where
f
::
forall
a
.
m
a
->
m
a
f
=
withAccessM
uId
id
src/Gargantext/API/Node.hs
View file @
a2dc9494
...
...
@@ -48,6 +48,7 @@ import Data.Swagger
import
Data.Text
(
Text
())
import
Data.Time
(
UTCTime
)
import
GHC.Generics
(
Generic
)
import
Gargantext.API.Auth
(
withAccess
)
import
Gargantext.API.Metrics
import
Gargantext.API.Ngrams
(
TabType
(
..
),
TableNgramsApi
,
apiNgramsTableCorpus
,
QueryParamR
,
TODO
)
import
Gargantext.API.Ngrams.NTree
(
MyTree
)
...
...
@@ -60,7 +61,7 @@ import Gargantext.Database.Facet (FacetDoc, OrderBy(..))
import
Gargantext.Database.Node.Children
(
getChildren
)
import
Gargantext.Database.Schema.Node
(
getNodesWithParentId
,
getNode
,
getNode'
,
deleteNode
,
deleteNodes
,
mkNodeWithParent
,
JSONB
,
HasNodeError
(
..
))
import
Gargantext.Database.Schema.NodeNode
(
nodeNodesCategory
)
import
Gargantext.Database.Tree
(
treeDB
,
isDescendantOf
)
import
Gargantext.Database.Tree
(
treeDB
)
import
Gargantext.Database.Types.Node
import
Gargantext.Database.Utils
-- (Cmd, CmdM)
import
Gargantext.Prelude
...
...
@@ -159,16 +160,10 @@ type ChildrenApi a = Summary " Summary children"
:>
QueryParam
"limit"
Int
:>
Get
'[
J
SON
]
[
Node
a
]
withAccess
::
(
CmdM
env
err
m
,
HasServerError
err
)
=>
UserId
->
NodeId
->
m
a
->
m
a
withAccess
uId
id
m
=
do
d
<-
id
`
isDescendantOf
`
NodeId
uId
printDebug
"withAccess"
(
uId
,
id
,
d
)
if
d
then
m
else
serverError
err401
------------------------------------------------------------------------
-- TODO: make the NodeId type indexed by `a`, then we no longer need the proxy.
nodeAPI
::
forall
proxy
a
.
(
JSONB
a
,
ToJSON
a
)
=>
proxy
a
->
UserId
->
NodeId
->
GargServer
(
NodeAPI
a
)
nodeAPI
p
uId
id
=
hoistServer
(
Proxy
::
Proxy
(
NodeAPI
a
))
(
withAccess
uId
id
)
nodeAPI'
nodeAPI
p
uId
id
=
withAccess
(
Proxy
::
Proxy
(
NodeAPI
a
))
Proxy
uId
id
nodeAPI'
where
nodeAPI'
::
GargServer
(
NodeAPI
a
)
nodeAPI'
=
getNode
id
p
...
...
@@ -315,8 +310,7 @@ instance HasTreeError ServantErr where
-}
type
TreeAPI
=
Get
'[
J
SON
]
(
Tree
NodeTree
)
-- TODO-ACCESS: CanTree or CanGetNode
-- TODO-EVENTS: No events as this is a read only query.
treeAPI
::
NodeId
->
GargServer
TreeAPI
treeAPI
=
treeDB
...
...
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