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
197
Issues
197
List
Board
Labels
Milestones
Merge Requests
11
Merge Requests
11
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