Initial minimal limited per-repo RBAC system
This commit is contained in:
parent
ada42dea62
commit
c0e8ed0d2e
16 changed files with 446 additions and 0 deletions
|
@ -53,6 +53,26 @@ GroupMember
|
||||||
|
|
||||||
UniqueGroupMember person group
|
UniqueGroupMember person group
|
||||||
|
|
||||||
|
Role
|
||||||
|
ident RlIdent
|
||||||
|
person PersonId
|
||||||
|
desc Text
|
||||||
|
|
||||||
|
UniqueRole person ident
|
||||||
|
|
||||||
|
Access
|
||||||
|
role RoleId
|
||||||
|
op Operation
|
||||||
|
|
||||||
|
UniqueAccess role op
|
||||||
|
|
||||||
|
Collab
|
||||||
|
repo RepoId
|
||||||
|
person PersonId
|
||||||
|
role RoleId
|
||||||
|
|
||||||
|
UniqueCollab repo person
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Projects
|
-- Projects
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
|
@ -50,6 +50,12 @@
|
||||||
/k/!new KeyNewR GET
|
/k/!new KeyNewR GET
|
||||||
/k/#KyIdent KeyR GET DELETE POST
|
/k/#KyIdent KeyR GET DELETE POST
|
||||||
|
|
||||||
|
/r RolesR GET POST
|
||||||
|
/r/!new RoleNewR GET
|
||||||
|
/r/#RlIdent RoleR GET DELETE POST
|
||||||
|
/r/#RlIdent/a RoleOpsR GET POST
|
||||||
|
/r/#RlIdent/a/!new RoleOpNewR GET
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
-- Projects
|
-- Projects
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -59,6 +59,7 @@ import Vervis.Handler.Key
|
||||||
import Vervis.Handler.Person
|
import Vervis.Handler.Person
|
||||||
import Vervis.Handler.Project
|
import Vervis.Handler.Project
|
||||||
import Vervis.Handler.Repo
|
import Vervis.Handler.Repo
|
||||||
|
import Vervis.Handler.Role
|
||||||
import Vervis.Handler.Sharer
|
import Vervis.Handler.Sharer
|
||||||
import Vervis.Handler.Ticket
|
import Vervis.Handler.Ticket
|
||||||
|
|
||||||
|
|
75
src/Vervis/Field/Role.hs
Normal file
75
src/Vervis/Field/Role.hs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{- This file is part of Vervis.
|
||||||
|
-
|
||||||
|
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
-
|
||||||
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
-
|
||||||
|
- The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
- rights to this software to the public domain worldwide. This software is
|
||||||
|
- distributed without any warranty.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
- with this software. If not, see
|
||||||
|
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Vervis.Field.Role
|
||||||
|
( newRoleIdentField
|
||||||
|
, newOpField
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
-- import Control.Monad (void)
|
||||||
|
-- import Control.Monad.Trans.Maybe
|
||||||
|
-- import Data.Char (isDigit)
|
||||||
|
-- import Data.Maybe (isNothing, isJust)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Database.Esqueleto
|
||||||
|
import Yesod.Form.Fields (textField, selectField, optionsEnum)
|
||||||
|
import Yesod.Form.Functions (checkM, convertField)
|
||||||
|
import Yesod.Form.Types (Field)
|
||||||
|
import Yesod.Persist.Core (runDB)
|
||||||
|
|
||||||
|
-- import qualified Data.Text as T (null, all, find, split)
|
||||||
|
|
||||||
|
-- import Data.Char.Local (isAsciiLetter)
|
||||||
|
import Vervis.Foundation (Handler, AppDB)
|
||||||
|
import Vervis.Model
|
||||||
|
import Vervis.Model.Ident (RlIdent, rl2text, text2rl)
|
||||||
|
import Vervis.Model.Role
|
||||||
|
|
||||||
|
checkUniqueCI :: PersonId -> Field Handler RlIdent -> Field Handler RlIdent
|
||||||
|
checkUniqueCI pid = checkM $ \ rl -> do
|
||||||
|
sames <- runDB $ select $ from $ \ role -> do
|
||||||
|
where_ $
|
||||||
|
role ^. RolePerson ==. val pid &&.
|
||||||
|
lower_ (role ^. RoleIdent) ==. lower_ (val rl)
|
||||||
|
limit 1
|
||||||
|
return ()
|
||||||
|
return $ if null sames
|
||||||
|
then Right rl
|
||||||
|
else Left ("This role name is already in use" :: Text)
|
||||||
|
|
||||||
|
roleIdentField :: Field Handler RlIdent
|
||||||
|
roleIdentField = convertField text2rl rl2text textField
|
||||||
|
|
||||||
|
newRoleIdentField :: PersonId -> Field Handler RlIdent
|
||||||
|
newRoleIdentField pid = checkUniqueCI pid roleIdentField
|
||||||
|
|
||||||
|
opField :: Field Handler Operation
|
||||||
|
opField = selectField optionsEnum
|
||||||
|
|
||||||
|
checkOpNew
|
||||||
|
:: AppDB RoleId -> Field Handler Operation -> Field Handler Operation
|
||||||
|
checkOpNew getrid = checkM $ \ op -> do
|
||||||
|
ma <- runDB $ do
|
||||||
|
rid <- getrid
|
||||||
|
getBy $ UniqueAccess rid op
|
||||||
|
return $ case ma of
|
||||||
|
Nothing -> Right op
|
||||||
|
Just _ -> Left ("Role already has this operation" :: Text)
|
||||||
|
|
||||||
|
newOpField :: AppDB RoleId -> Field Handler Operation
|
||||||
|
newOpField getrid = checkOpNew getrid opField
|
53
src/Vervis/Form/Role.hs
Normal file
53
src/Vervis/Form/Role.hs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{- This file is part of Vervis.
|
||||||
|
-
|
||||||
|
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
-
|
||||||
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
-
|
||||||
|
- The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
- rights to this software to the public domain worldwide. This software is
|
||||||
|
- distributed without any warranty.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
- with this software. If not, see
|
||||||
|
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Vervis.Form.Role
|
||||||
|
( NewRole (..)
|
||||||
|
, newRoleForm
|
||||||
|
, newRoleOpForm
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Yesod.Form.Fields (textField)
|
||||||
|
import Yesod.Form.Functions (areq, renderDivs)
|
||||||
|
import Yesod.Form.Types (AForm)
|
||||||
|
|
||||||
|
import Vervis.Field.Role
|
||||||
|
import Vervis.Foundation (Handler, Form, AppDB)
|
||||||
|
import Vervis.Model
|
||||||
|
import Vervis.Model.Ident (RlIdent)
|
||||||
|
import Vervis.Model.Role
|
||||||
|
|
||||||
|
data NewRole = NewRole
|
||||||
|
{ nrIdent :: RlIdent
|
||||||
|
, nrDesc :: Text
|
||||||
|
}
|
||||||
|
|
||||||
|
newRoleAForm :: PersonId -> AForm Handler NewRole
|
||||||
|
newRoleAForm pid = NewRole
|
||||||
|
<$> areq (newRoleIdentField pid) "Name*" Nothing
|
||||||
|
<*> areq textField "Description" Nothing
|
||||||
|
|
||||||
|
newRoleForm :: PersonId -> Form NewRole
|
||||||
|
newRoleForm pid = renderDivs $ newRoleAForm pid
|
||||||
|
|
||||||
|
newRoleOpAForm :: AppDB RoleId -> AForm Handler Operation
|
||||||
|
newRoleOpAForm getrid = areq (newOpField getrid) "Operation*" Nothing
|
||||||
|
|
||||||
|
newRoleOpForm :: AppDB RoleId -> Form Operation
|
||||||
|
newRoleOpForm getrid = renderDivs $ newRoleOpAForm getrid
|
|
@ -129,6 +129,12 @@ instance Yesod App where
|
||||||
(KeyR _key , _ ) -> personAny
|
(KeyR _key , _ ) -> personAny
|
||||||
(KeyNewR , _ ) -> personAny
|
(KeyNewR , _ ) -> personAny
|
||||||
|
|
||||||
|
(RolesR , _ ) -> personAny
|
||||||
|
(RoleNewR , _ ) -> personAny
|
||||||
|
(RoleR _rl , _ ) -> personAny
|
||||||
|
(RoleOpsR _rl , _ ) -> personAny
|
||||||
|
(RoleOpNewR _rl , _ ) -> personAny
|
||||||
|
|
||||||
(ReposR shar , True) -> person shar
|
(ReposR shar , True) -> person shar
|
||||||
(RepoNewR user , _ ) -> person user
|
(RepoNewR user , _ ) -> person user
|
||||||
(RepoR shar _ , True) -> person shar
|
(RepoR shar _ , True) -> person shar
|
||||||
|
@ -283,11 +289,21 @@ instance YesodBreadcrumbs App where
|
||||||
GroupNewR -> ("New", Just GroupsR)
|
GroupNewR -> ("New", Just GroupsR)
|
||||||
GroupR shar -> (shr2text shar, Just GroupsR)
|
GroupR shar -> (shr2text shar, Just GroupsR)
|
||||||
GroupMembersR shar -> ("Members", Just $ GroupR shar)
|
GroupMembersR shar -> ("Members", Just $ GroupR shar)
|
||||||
|
GroupMemberNewR shar -> ("New", Just $ GroupMembersR shar)
|
||||||
|
GroupMemberR grp memb -> ( shr2text memb
|
||||||
|
, Just $ GroupMembersR grp
|
||||||
|
)
|
||||||
|
|
||||||
KeysR -> ("Keys", Just HomeR)
|
KeysR -> ("Keys", Just HomeR)
|
||||||
KeyNewR -> ("New", Just KeysR)
|
KeyNewR -> ("New", Just KeysR)
|
||||||
KeyR key -> (ky2text key, Just KeysR)
|
KeyR key -> (ky2text key, Just KeysR)
|
||||||
|
|
||||||
|
RolesR -> ("Roles", Just HomeR)
|
||||||
|
RoleNewR -> ("New", Just RolesR)
|
||||||
|
RoleR rl -> (rl2text rl, Just RolesR)
|
||||||
|
RoleOpsR rl -> ("Operations", Just $ RoleR rl)
|
||||||
|
RoleOpNewR rl -> ("New", Just $ RoleOpsR rl)
|
||||||
|
|
||||||
ReposR shar -> ("Repos", Just $ PersonR shar)
|
ReposR shar -> ("Repos", Just $ PersonR shar)
|
||||||
RepoNewR shar -> ("New", Just $ ReposR shar)
|
RepoNewR shar -> ("New", Just $ ReposR shar)
|
||||||
RepoR shar repo -> (rp2text repo, Just $ ReposR shar)
|
RepoR shar repo -> (rp2text repo, Just $ ReposR shar)
|
||||||
|
|
136
src/Vervis/Handler/Role.hs
Normal file
136
src/Vervis/Handler/Role.hs
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
{- This file is part of Vervis.
|
||||||
|
-
|
||||||
|
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
-
|
||||||
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
-
|
||||||
|
- The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
- rights to this software to the public domain worldwide. This software is
|
||||||
|
- distributed without any warranty.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
- with this software. If not, see
|
||||||
|
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Vervis.Handler.Role
|
||||||
|
( getRolesR
|
||||||
|
, postRolesR
|
||||||
|
, getRoleNewR
|
||||||
|
, getRoleR
|
||||||
|
, deleteRoleR
|
||||||
|
, postRoleR
|
||||||
|
, getRoleOpsR
|
||||||
|
, postRoleOpsR
|
||||||
|
, getRoleOpNewR
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Database.Persist
|
||||||
|
import Text.Blaze.Html (Html)
|
||||||
|
import Yesod.Auth (requireAuthId)
|
||||||
|
import Yesod.Core (defaultLayout, setMessage)
|
||||||
|
import Yesod.Core.Handler (lookupPostParam, notFound, redirect)
|
||||||
|
import Yesod.Form.Functions (runFormPost)
|
||||||
|
import Yesod.Form.Types (FormResult (..))
|
||||||
|
import Yesod.Persist.Core (runDB, getBy404)
|
||||||
|
|
||||||
|
import Vervis.Form.Role
|
||||||
|
import Vervis.Foundation
|
||||||
|
import Vervis.Model
|
||||||
|
import Vervis.Model.Ident (RlIdent, rl2text)
|
||||||
|
import Vervis.Settings (widgetFile)
|
||||||
|
|
||||||
|
getRolesR :: Handler Html
|
||||||
|
getRolesR = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
roles <- runDB $ selectList [RolePerson ==. pid] []
|
||||||
|
defaultLayout $(widgetFile "role/list")
|
||||||
|
|
||||||
|
postRolesR :: Handler Html
|
||||||
|
postRolesR = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
((result, widget), enctype) <- runFormPost $ newRoleForm pid
|
||||||
|
case result of
|
||||||
|
FormSuccess nr -> do
|
||||||
|
runDB $ do
|
||||||
|
let role = Role
|
||||||
|
{ roleIdent = nrIdent nr
|
||||||
|
, rolePerson = pid
|
||||||
|
, roleDesc = nrDesc nr
|
||||||
|
}
|
||||||
|
insert_ role
|
||||||
|
redirect $ RolesR
|
||||||
|
FormMissing -> do
|
||||||
|
setMessage "Field(s) missing"
|
||||||
|
defaultLayout $(widgetFile "role/new")
|
||||||
|
FormFailure _l -> do
|
||||||
|
setMessage "Invalid input, see errors below"
|
||||||
|
defaultLayout $(widgetFile "role/new")
|
||||||
|
|
||||||
|
getRoleNewR :: Handler Html
|
||||||
|
getRoleNewR = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
((_result, widget), enctype) <- runFormPost $ newRoleForm pid
|
||||||
|
defaultLayout $(widgetFile "role/new")
|
||||||
|
|
||||||
|
getRoleR :: RlIdent -> Handler Html
|
||||||
|
getRoleR rl = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
Entity _rid role <- runDB $ getBy404 $ UniqueRole pid rl
|
||||||
|
defaultLayout $(widgetFile "role/one")
|
||||||
|
|
||||||
|
deleteRoleR :: RlIdent -> Handler Html
|
||||||
|
deleteRoleR rl = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
runDB $ do
|
||||||
|
Entity rid _r <- getBy404 $ UniqueRole pid rl
|
||||||
|
delete rid
|
||||||
|
setMessage "Role deleted."
|
||||||
|
redirect RolesR
|
||||||
|
|
||||||
|
postRoleR :: RlIdent -> Handler Html
|
||||||
|
postRoleR rl = do
|
||||||
|
mmethod <- lookupPostParam "_method"
|
||||||
|
case mmethod of
|
||||||
|
Just "DELETE" -> deleteRoleR rl
|
||||||
|
_ -> notFound
|
||||||
|
|
||||||
|
getRoleOpsR :: RlIdent -> Handler Html
|
||||||
|
getRoleOpsR rl = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
ops <- runDB $ do
|
||||||
|
Entity rid _r <- getBy404 $ UniqueRole pid rl
|
||||||
|
map (accessOp . entityVal) <$> selectList [AccessRole ==. rid] []
|
||||||
|
defaultLayout $(widgetFile "role/op/list")
|
||||||
|
|
||||||
|
postRoleOpsR :: RlIdent -> Handler Html
|
||||||
|
postRoleOpsR rl = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
let getrid = fmap entityKey $ getBy404 $ UniqueRole pid rl
|
||||||
|
((result, widget), enctype) <- runFormPost $ newRoleOpForm getrid
|
||||||
|
case result of
|
||||||
|
FormSuccess op -> do
|
||||||
|
runDB $ do
|
||||||
|
rid <- getrid
|
||||||
|
let access = Access
|
||||||
|
{ accessRole = rid
|
||||||
|
, accessOp = op
|
||||||
|
}
|
||||||
|
insert_ access
|
||||||
|
redirect $ RoleOpsR rl
|
||||||
|
FormMissing -> do
|
||||||
|
setMessage "Field(s) missing"
|
||||||
|
defaultLayout $(widgetFile "role/op/new")
|
||||||
|
FormFailure _l -> do
|
||||||
|
setMessage "Invalid input, see errors below"
|
||||||
|
defaultLayout $(widgetFile "role/op/new")
|
||||||
|
|
||||||
|
getRoleOpNewR :: RlIdent -> Handler Html
|
||||||
|
getRoleOpNewR rl = do
|
||||||
|
pid <- requireAuthId
|
||||||
|
let getrid = fmap entityKey $ getBy404 $ UniqueRole pid rl
|
||||||
|
((_result, widget), enctype) <- runFormPost $ newRoleOpForm getrid
|
||||||
|
defaultLayout $(widgetFile "role/op/new")
|
|
@ -27,6 +27,7 @@ import Yesod.Auth.HashDB (HashDBUser (..))
|
||||||
import Vervis.Model.Group
|
import Vervis.Model.Group
|
||||||
import Vervis.Model.Ident
|
import Vervis.Model.Ident
|
||||||
import Vervis.Model.Repo
|
import Vervis.Model.Repo
|
||||||
|
import Vervis.Model.Role
|
||||||
|
|
||||||
-- You can define all of your database entities in the entities file.
|
-- You can define all of your database entities in the entities file.
|
||||||
-- You can find more information on persistent and how to declare entities at:
|
-- You can find more information on persistent and how to declare entities at:
|
||||||
|
|
|
@ -22,6 +22,9 @@ module Vervis.Model.Ident
|
||||||
, KyIdent (..)
|
, KyIdent (..)
|
||||||
, ky2text
|
, ky2text
|
||||||
, text2ky
|
, text2ky
|
||||||
|
, RlIdent (..)
|
||||||
|
, rl2text
|
||||||
|
, text2rl
|
||||||
, PrjIdent (..)
|
, PrjIdent (..)
|
||||||
, prj2text
|
, prj2text
|
||||||
, text2prj
|
, text2prj
|
||||||
|
@ -67,6 +70,16 @@ ky2text = CI.original . unKyIdent
|
||||||
text2ky :: Text -> KyIdent
|
text2ky :: Text -> KyIdent
|
||||||
text2ky = KyIdent . CI.mk
|
text2ky = KyIdent . CI.mk
|
||||||
|
|
||||||
|
newtype RlIdent = RlIdent { unRlIdent :: CI Text }
|
||||||
|
deriving
|
||||||
|
(Eq, Show, Read, PersistField, PersistFieldSql, SqlString, PathPiece)
|
||||||
|
|
||||||
|
rl2text :: RlIdent -> Text
|
||||||
|
rl2text = CI.original . unRlIdent
|
||||||
|
|
||||||
|
text2rl :: Text -> RlIdent
|
||||||
|
text2rl = RlIdent . CI.mk
|
||||||
|
|
||||||
newtype PrjIdent = PrjIdent { unPrjIdent :: CI Text }
|
newtype PrjIdent = PrjIdent { unPrjIdent :: CI Text }
|
||||||
deriving
|
deriving
|
||||||
(Eq, Show, Read, PersistField, PersistFieldSql, SqlString, PathPiece)
|
(Eq, Show, Read, PersistField, PersistFieldSql, SqlString, PathPiece)
|
||||||
|
|
27
src/Vervis/Model/Role.hs
Normal file
27
src/Vervis/Model/Role.hs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{- This file is part of Vervis.
|
||||||
|
-
|
||||||
|
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
-
|
||||||
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
-
|
||||||
|
- The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
- rights to this software to the public domain worldwide. This software is
|
||||||
|
- distributed without any warranty.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
- with this software. If not, see
|
||||||
|
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Vervis.Model.Role
|
||||||
|
( Operation (..)
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Database.Persist.TH
|
||||||
|
|
||||||
|
data Operation = OpRepoPush deriving (Eq, Show, Read, Enum, Bounded)
|
||||||
|
|
||||||
|
derivePersistField "Operation"
|
18
templates/role/list.hamlet
Normal file
18
templates/role/list.hamlet
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
$# This file is part of Vervis.
|
||||||
|
$#
|
||||||
|
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
$#
|
||||||
|
$# ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
$#
|
||||||
|
$# The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
$# rights to this software to the public domain worldwide. This software is
|
||||||
|
$# distributed without any warranty.
|
||||||
|
$#
|
||||||
|
$# You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
$# with this software. If not, see
|
||||||
|
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
$forall Entity _rid role <- roles
|
||||||
|
<li>
|
||||||
|
<a href=@{RoleR $ roleIdent role}>#{rl2text $ roleIdent role}
|
17
templates/role/new.hamlet
Normal file
17
templates/role/new.hamlet
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
$# This file is part of Vervis.
|
||||||
|
$#
|
||||||
|
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
$#
|
||||||
|
$# ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
$#
|
||||||
|
$# The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
$# rights to this software to the public domain worldwide. This software is
|
||||||
|
$# distributed without any warranty.
|
||||||
|
$#
|
||||||
|
$# You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
$# with this software. If not, see
|
||||||
|
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
<form method=POST action=@{RolesR} enctype=#{enctype}>
|
||||||
|
^{widget}
|
||||||
|
<input type=submit>
|
24
templates/role/one.hamlet
Normal file
24
templates/role/one.hamlet
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
$# This file is part of Vervis.
|
||||||
|
$#
|
||||||
|
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
$#
|
||||||
|
$# ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
$#
|
||||||
|
$# The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
$# rights to this software to the public domain worldwide. This software is
|
||||||
|
$# distributed without any warranty.
|
||||||
|
$#
|
||||||
|
$# You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
$# with this software. If not, see
|
||||||
|
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<form method=POST action=@{RoleR rl}>
|
||||||
|
<input type=hidden name=_method value=DELETE>
|
||||||
|
<input type=submit value="Delete this role">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href=@{RoleOpsR rl}>Operations
|
||||||
|
|
||||||
|
<p>
|
||||||
|
#{roleDesc role}
|
18
templates/role/op/list.hamlet
Normal file
18
templates/role/op/list.hamlet
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
$# This file is part of Vervis.
|
||||||
|
$#
|
||||||
|
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
$#
|
||||||
|
$# ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
$#
|
||||||
|
$# The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
$# rights to this software to the public domain worldwide. This software is
|
||||||
|
$# distributed without any warranty.
|
||||||
|
$#
|
||||||
|
$# You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
$# with this software. If not, see
|
||||||
|
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
$forall op <- ops
|
||||||
|
<li>
|
||||||
|
#{show op}
|
17
templates/role/op/new.hamlet
Normal file
17
templates/role/op/new.hamlet
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
$# This file is part of Vervis.
|
||||||
|
$#
|
||||||
|
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
$#
|
||||||
|
$# ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
$#
|
||||||
|
$# The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
$# rights to this software to the public domain worldwide. This software is
|
||||||
|
$# distributed without any warranty.
|
||||||
|
$#
|
||||||
|
$# You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
$# with this software. If not, see
|
||||||
|
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
<form method=POST action=@{RoleOpsR rl} enctype=#{enctype}>
|
||||||
|
^{widget}
|
||||||
|
<input type=submit>
|
|
@ -84,6 +84,7 @@ library
|
||||||
Vervis.Field.Person
|
Vervis.Field.Person
|
||||||
Vervis.Field.Project
|
Vervis.Field.Project
|
||||||
Vervis.Field.Repo
|
Vervis.Field.Repo
|
||||||
|
Vervis.Field.Role
|
||||||
Vervis.Field.Sharer
|
Vervis.Field.Sharer
|
||||||
Vervis.Form.Discussion
|
Vervis.Form.Discussion
|
||||||
Vervis.Form.Group
|
Vervis.Form.Group
|
||||||
|
@ -91,6 +92,7 @@ library
|
||||||
Vervis.Form.Person
|
Vervis.Form.Person
|
||||||
Vervis.Form.Project
|
Vervis.Form.Project
|
||||||
Vervis.Form.Repo
|
Vervis.Form.Repo
|
||||||
|
Vervis.Form.Role
|
||||||
Vervis.Form.Ticket
|
Vervis.Form.Ticket
|
||||||
Vervis.Formatting
|
Vervis.Formatting
|
||||||
Vervis.Foundation
|
Vervis.Foundation
|
||||||
|
@ -107,6 +109,7 @@ library
|
||||||
Vervis.Handler.Repo
|
Vervis.Handler.Repo
|
||||||
Vervis.Handler.Repo.Darcs
|
Vervis.Handler.Repo.Darcs
|
||||||
Vervis.Handler.Repo.Git
|
Vervis.Handler.Repo.Git
|
||||||
|
Vervis.Handler.Role
|
||||||
Vervis.Handler.Sharer
|
Vervis.Handler.Sharer
|
||||||
Vervis.Handler.Ticket
|
Vervis.Handler.Ticket
|
||||||
Vervis.Import
|
Vervis.Import
|
||||||
|
@ -116,6 +119,7 @@ library
|
||||||
Vervis.Model.Group
|
Vervis.Model.Group
|
||||||
Vervis.Model.Ident
|
Vervis.Model.Ident
|
||||||
Vervis.Model.Repo
|
Vervis.Model.Repo
|
||||||
|
Vervis.Model.Role
|
||||||
Vervis.Paginate
|
Vervis.Paginate
|
||||||
Vervis.Path
|
Vervis.Path
|
||||||
Vervis.Readme
|
Vervis.Readme
|
||||||
|
|
Loading…
Reference in a new issue