Various fixes
14
CHANGELOG.md
@@ -1,12 +1,4 @@
|
||||
owncloud-deck (0.1.0)
|
||||
* **Enhancement**: First public release
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Sharing boards with other users
|
||||
|
||||
-------------------
|
||||
Template:
|
||||
|
||||
owncloud-deck (0.1.0)
|
||||
* **Security**: Security description here
|
||||
* **Backwards incompatible change**: Changes in the API
|
||||
* **New dependency**: New dependencies such as a new ownCloud or PHP version
|
||||
* **Bugfix**: Bugfix description
|
||||
* **Enhancement**: New feature description
|
||||
|
||||
@@ -253,86 +253,6 @@
|
||||
</field>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*deck_acl_users</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>board_id</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>8</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>permission_write</name>
|
||||
<type>boolean</type>
|
||||
<default>false</default>
|
||||
</field>
|
||||
<field>
|
||||
<name>permission_invite</name>
|
||||
<type>boolean</type>
|
||||
<default>false</default>
|
||||
</field>
|
||||
<field>
|
||||
<name>permission_manage</name>
|
||||
<type>boolean</type>
|
||||
<default>false</default>
|
||||
</field>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*deck_acl_groups</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>board_id</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>8</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>group_id</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>permission_write</name>
|
||||
<type>boolean</type>
|
||||
<default>false</default>
|
||||
</field>
|
||||
<field>
|
||||
<name>permission_invite</name>
|
||||
<type>boolean</type>
|
||||
<default>false</default>
|
||||
</field>
|
||||
<field>
|
||||
<name>permission_manage</name>
|
||||
<type>boolean</type>
|
||||
<default>false</default>
|
||||
</field>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*deck_board_acl</name>
|
||||
<declaration>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
|
||||
<id>deck</id>
|
||||
<name>Deck</name>
|
||||
<description>My first ownCloud app</description>
|
||||
<licence>AGPL</licence>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<version>0.0.1.14</version>
|
||||
<namespace>Deck</namespace>
|
||||
<category>other</category>
|
||||
<category>Other
|
||||
</category>
|
||||
<dependencies>
|
||||
<owncloud min-version="9.0" max-version="9.2" />
|
||||
<owncloud min-version="9.1" max-version="9.2" />
|
||||
<nextcloud min-version="10" max-version="11" />
|
||||
</dependencies>
|
||||
</info>
|
||||
|
||||
@@ -62,8 +62,5 @@ return [
|
||||
['name' => 'label#update', 'url' => '/labels/{labelId}', 'verb' => 'PUT'],
|
||||
['name' => 'label#delete', 'url' => '/labels/{labelId}', 'verb' => 'DELETE'],
|
||||
|
||||
// TODO: Implement public board sharing
|
||||
// TODO: API for external access
|
||||
|
||||
]
|
||||
];
|
||||
|
||||
2221
css/font-awesome.css
vendored
@@ -191,11 +191,12 @@
|
||||
font-size: 12pt;
|
||||
font-weight: 700;
|
||||
overflow: hidden;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.stack h2 input {
|
||||
padding: 0px;
|
||||
width: 90%;
|
||||
width: 80%;
|
||||
padding-bottom: 3px;
|
||||
margin: 0;
|
||||
font-size: 12pt;
|
||||
@@ -212,7 +213,6 @@
|
||||
|
||||
.stack h2 span {
|
||||
float: left;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.stack h2 .stack-actions {
|
||||
|
||||
54
img/app.svg
@@ -1,53 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{display:none;}
|
||||
.st1{display:inline;}
|
||||
.st2{fill:#0071BC;}
|
||||
.st3{display:inline;fill:#FFFFFF;}
|
||||
.st4{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g id="Ebene_2" class="st0">
|
||||
<g class="st1">
|
||||
<path class="st2" d="M1,444C1,318.7,1,193.3,1,68c1.3-5.1,2.3-10.3,3.9-15.4c10.6-32.5,39-52.5,74.5-52.5c118.4,0,236.8,0,355.2,0
|
||||
c2.3,0,4.7,0,7,0.2c29,2.6,50.7,16.4,63.5,42.7c3.8,7.8,5.3,16.6,7.9,25c0,125.3,0,250.7,0,376c-0.4,1.1-0.9,2.1-1,3.2
|
||||
c-4.4,26.1-18.2,45.4-42,56.9c-7.8,3.7-16.6,5.3-24.9,7.9c-125.3,0-250.7,0-376,0c-1.1-0.4-2.1-0.9-3.2-1
|
||||
c-26.1-4.4-45.4-18.2-56.9-42C5.2,461.2,3.6,452.3,1,444z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Ebene_4" class="st0">
|
||||
<rect x="1" y="-18.8" class="st1" width="511" height="530.8"/>
|
||||
</g>
|
||||
<g id="Ebene_1" class="st0">
|
||||
<path class="st3" d="M164,144H81c-6.6,0-12-5.4-12-12V80c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52C176,138.6,170.6,144,164,144
|
||||
z"/>
|
||||
<path class="st3" d="M164,244.3H81c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C176,238.9,170.6,244.3,164,244.3z"/>
|
||||
<path class="st3" d="M164,344.6H81c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C176,339.2,170.6,344.6,164,344.6z"/>
|
||||
<path class="st3" d="M164,444H81c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C176,438.6,170.6,444,164,444z"/>
|
||||
<path class="st3" d="M433,144h-83c-6.6,0-12-5.4-12-12V80c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C445,138.6,439.6,144,433,144z"/>
|
||||
<path class="st3" d="M433,244.3h-83c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C445,238.9,439.6,244.3,433,244.3z"/>
|
||||
<path class="st3" d="M433,344.6h-83c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C445,339.2,439.6,344.6,433,344.6z"/>
|
||||
<path class="st3" d="M297.5,144h-83c-6.6,0-12-5.4-12-12V80c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C309.5,138.6,304.1,144,297.5,144z"/>
|
||||
<path class="st3" d="M297.5,244.3h-83c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C309.5,238.9,304.1,244.3,297.5,244.3z"/>
|
||||
</g>
|
||||
<g id="Ebene_3">
|
||||
<path class="st4" d="M432.3,448.1h-348c-13.2,0-24-10.8-24-24V264.6c0-13.2,10.8-24,24-24h348c13.2,0,24,10.8,24,24v159.5
|
||||
C456.3,437.3,445.5,448.1,432.3,448.1z"/>
|
||||
<path class="st4" d="M380.4,89.8H127.8c-7.7,0-14-6.3-14-14v-6.3c0-7.7,6.3-14,14-14h252.6c7.7,0,14,6.3,14,14v6.3
|
||||
C394.4,83.5,388.1,89.8,380.4,89.8z"/>
|
||||
<path class="st4" d="M399.8,151.6H110.6c-7.7,0-14-6.3-14-14v-6.3c0-7.7,6.3-14,14-14h289.2c7.7,0,14,6.3,14,14v6.3
|
||||
C413.8,145.3,407.5,151.6,399.8,151.6z"/>
|
||||
<path class="st4" d="M421.4,213H94.6c-7.7,0-14-6.3-14-14v-6.3c0-7.7,6.3-14,14-14h326.8c7.7,0,14,6.3,14,14v6.3
|
||||
C435.4,206.7,429.1,213,421.4,213z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><style>.st0{display:none}.st1{display:inline}.st2{fill:#0071bc}.st3{display:inline}.st3,.st4{fill:#fff}</style><path class="st0 st1 st2" d="M1 444V68c1.3-5.1 2.3-10.3 3.9-15.4C15.5 20.1 43.9.1 79.4.1h355.2c2.3 0 4.7 0 7 .2 29 2.6 50.7 16.4 63.5 42.7 3.8 7.8 5.3 16.6 7.9 25v376c-.4 1.1-.9 2.1-1 3.2-4.4 26.1-18.2 45.4-42 56.9-7.8 3.7-16.6 5.3-24.9 7.9h-376c-1.1-.4-2.1-.9-3.2-1-26.1-4.4-45.4-18.2-56.9-42-3.8-7.8-5.4-16.7-8-25z" id="Ebene_2"/><path class="st0 st1" d="M1-18.8h511V512H1z" id="Ebene_4"/><g id="Ebene_1" class="st0"><path class="st3" d="M164 144H81c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM164 244.3H81c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM164 344.6H81c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM164 444H81c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM433 144h-83c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM433 244.3h-83c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM433 344.6h-83c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM297.5 144h-83c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM297.5 244.3h-83c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12z"/></g><g id="Ebene_3"><path class="st4" d="M432.3 448.1h-348c-13.2 0-24-10.8-24-24V264.6c0-13.2 10.8-24 24-24h348c13.2 0 24 10.8 24 24v159.5c0 13.2-10.8 24-24 24zM380.4 89.8H127.8c-7.7 0-14-6.3-14-14v-6.3c0-7.7 6.3-14 14-14h252.6c7.7 0 14 6.3 14 14v6.3c0 7.7-6.3 14-14 14zM399.8 151.6H110.6c-7.7 0-14-6.3-14-14v-6.3c0-7.7 6.3-14 14-14h289.2c7.7 0 14 6.3 14 14v6.3c0 7.7-6.3 14-14 14zM421.4 213H94.6c-7.7 0-14-6.3-14-14v-6.3c0-7.7 6.3-14 14-14h326.8c7.7 0 14 6.3 14 14v6.3c0 7.7-6.3 14-14 14z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -1,71 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="archive-white.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="64"
|
||||
inkscape:cx="6.7874687"
|
||||
inkscape:cy="12.390933"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1918"
|
||||
inkscape:window-height="1039"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="18"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 1.9295646,1041.2962 c -0.1850528,0 -0.3352657,0.1378 -0.3352657,0.3101 l 0,9.8421 c 0,0.1721 0.1502129,0.3122 0.3352657,0.3122 l 12.5173544,0 c 0.185052,0 0.332969,-0.1401 0.332969,-0.3122 l 0,-9.8421 c 0,-0.1723 -0.147917,-0.3101 -0.332969,-0.3101 l -12.5173544,0 z m 4.1242283,1.5065 4.2229711,0 c 0.390666,0 0.704976,0.3143 0.704976,0.7048 l 0,0.4295 c 0,0.3906 -0.31431,0.705 -0.704976,0.705 l -4.2229711,0 c -0.3906669,0 -0.7049766,-0.3144 -0.7049766,-0.705 l 0,-0.4295 c 0,-0.3905 0.3143097,-0.7048 0.7049766,-0.7048 z"
|
||||
id="rect5234"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect5238"
|
||||
width="15.742155"
|
||||
height="2.2959547"
|
||||
x="0.13577603"
|
||||
y="1037.543"
|
||||
ry="0" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><g transform="translate(0 -1036.362)" fill="#fff"><path d="M1.93 1041.296c-.185 0-.336.138-.336.31v9.842c0 .172.15.313.336.313h12.517c.185 0 .333-.14.333-.313v-9.842c0-.172-.148-.31-.333-.31H1.93zm4.124 1.507h4.223c.39 0 .705.314.705.704v.43c0 .39-.315.705-.705.705H6.054a.703.703 0 0 1-.705-.705v-.43c0-.39.314-.704.705-.704z"/><rect width="15.742" height="2.296" x=".136" y="1037.543" ry="0"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 488 B |
@@ -1,71 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="archive.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="2.586198"
|
||||
inkscape:cy="-3.3073701"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1918"
|
||||
inkscape:window-height="1039"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="18"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 1.9295646,1041.2962 c -0.1850528,0 -0.3352657,0.1378 -0.3352657,0.3101 l 0,9.8421 c 0,0.1721 0.1502129,0.3122 0.3352657,0.3122 l 12.5173544,0 c 0.185052,0 0.332969,-0.1401 0.332969,-0.3122 l 0,-9.8421 c 0,-0.1723 -0.147917,-0.3101 -0.332969,-0.3101 l -12.5173544,0 z m 4.1242283,1.5065 4.2229711,0 c 0.390666,0 0.704976,0.3143 0.704976,0.7048 l 0,0.4295 c 0,0.3906 -0.31431,0.705 -0.704976,0.705 l -4.2229711,0 c -0.3906669,0 -0.7049766,-0.3144 -0.7049766,-0.705 l 0,-0.4295 c 0,-0.3905 0.3143097,-0.7048 0.7049766,-0.7048 z"
|
||||
id="rect5234"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect5238"
|
||||
width="15.742155"
|
||||
height="2.2959547"
|
||||
x="0.13577603"
|
||||
y="1037.543"
|
||||
ry="0.41990235" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><g transform="translate(0 -1036.362)"><path d="M1.93 1041.296c-.185 0-.336.138-.336.31v9.842c0 .172.15.313.336.313h12.517c.185 0 .333-.14.333-.313v-9.842c0-.172-.148-.31-.333-.31H1.93zm4.124 1.507h4.223c.39 0 .705.314.705.704v.43c0 .39-.315.705-.705.705H6.054a.703.703 0 0 1-.705-.705v-.43c0-.39.314-.704.705-.704z"/><rect width="15.742" height="2.296" x=".136" y="1037.543" ry=".42"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 478 B |
@@ -1,61 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="16"
|
||||
width="16"
|
||||
version="1.0"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="details-white.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1918"
|
||||
inkscape:window-height="1039"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-8.0677966"
|
||||
inkscape:cy="8"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="18"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff"
|
||||
fill-opacity="0"
|
||||
height="97.986"
|
||||
width="163.31"
|
||||
y="-32.993"
|
||||
x="-62.897"
|
||||
id="rect4" />
|
||||
<path
|
||||
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0;fill:#ffffff"
|
||||
d="m2 3v3h3v-3h-3zm4 1v1h8v-1h-8zm-4 3v3h3v-3h-3zm4 1v1h8v-1h-8zm-4 3v3h3v-3h-3zm1 1h1v1h-1v-1zm3 0v1h8v-1h-8z"
|
||||
id="path6" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path color="#000" fill="none" d="M-62.897-32.993h163.31v97.986h-163.31z"/><path style="block-progression:tb;text-transform:none;text-indent:0" d="M2 3v3h3V3H2zm4 1v1h8V4H6zM2 7v3h3V7H2zm4 1v1h8V8H6zm-4 3v3h3v-3H2zm1 1h1v1H3v-1zm3 0v1h8v-1H6z" color="#000" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 351 B |
@@ -1,53 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{display:none;}
|
||||
.st1{display:inline;}
|
||||
.st2{fill:#0071BC;}
|
||||
.st3{display:inline;fill:#FFFFFF;}
|
||||
.st4{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g id="Ebene_2" class="st0">
|
||||
<g class="st1">
|
||||
<path class="st2" d="M1,444C1,318.7,1,193.3,1,68c1.3-5.1,2.3-10.3,3.9-15.4c10.6-32.5,39-52.5,74.5-52.5c118.4,0,236.8,0,355.2,0
|
||||
c2.3,0,4.7,0,7,0.2c29,2.6,50.7,16.4,63.5,42.7c3.8,7.8,5.3,16.6,7.9,25c0,125.3,0,250.7,0,376c-0.4,1.1-0.9,2.1-1,3.2
|
||||
c-4.4,26.1-18.2,45.4-42,56.9c-7.8,3.7-16.6,5.3-24.9,7.9c-125.3,0-250.7,0-376,0c-1.1-0.4-2.1-0.9-3.2-1
|
||||
c-26.1-4.4-45.4-18.2-56.9-42C5.2,461.2,3.6,452.3,1,444z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Ebene_4" class="st0">
|
||||
<rect x="1" y="-18.8" class="st1" width="511" height="530.8"/>
|
||||
</g>
|
||||
<g id="Ebene_1" class="st0">
|
||||
<path class="st3" d="M164,144H81c-6.6,0-12-5.4-12-12V80c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52C176,138.6,170.6,144,164,144
|
||||
z"/>
|
||||
<path class="st3" d="M164,244.3H81c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C176,238.9,170.6,244.3,164,244.3z"/>
|
||||
<path class="st3" d="M164,344.6H81c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C176,339.2,170.6,344.6,164,344.6z"/>
|
||||
<path class="st3" d="M164,444H81c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C176,438.6,170.6,444,164,444z"/>
|
||||
<path class="st3" d="M433,144h-83c-6.6,0-12-5.4-12-12V80c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C445,138.6,439.6,144,433,144z"/>
|
||||
<path class="st3" d="M433,244.3h-83c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C445,238.9,439.6,244.3,433,244.3z"/>
|
||||
<path class="st3" d="M433,344.6h-83c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C445,339.2,439.6,344.6,433,344.6z"/>
|
||||
<path class="st3" d="M297.5,144h-83c-6.6,0-12-5.4-12-12V80c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C309.5,138.6,304.1,144,297.5,144z"/>
|
||||
<path class="st3" d="M297.5,244.3h-83c-6.6,0-12-5.4-12-12v-52c0-6.6,5.4-12,12-12h83c6.6,0,12,5.4,12,12v52
|
||||
C309.5,238.9,304.1,244.3,297.5,244.3z"/>
|
||||
</g>
|
||||
<g id="Ebene_3">
|
||||
<path class="st4" d="M432.3,448.1h-348c-13.2,0-24-10.8-24-24V264.6c0-13.2,10.8-24,24-24h348c13.2,0,24,10.8,24,24v159.5
|
||||
C456.3,437.3,445.5,448.1,432.3,448.1z"/>
|
||||
<path class="st4" d="M380.4,89.8H127.8c-7.7,0-14-6.3-14-14v-6.3c0-7.7,6.3-14,14-14h252.6c7.7,0,14,6.3,14,14v6.3
|
||||
C394.4,83.5,388.1,89.8,380.4,89.8z"/>
|
||||
<path class="st4" d="M399.8,151.6H110.6c-7.7,0-14-6.3-14-14v-6.3c0-7.7,6.3-14,14-14h289.2c7.7,0,14,6.3,14,14v6.3
|
||||
C413.8,145.3,407.5,151.6,399.8,151.6z"/>
|
||||
<path class="st4" d="M421.4,213H94.6c-7.7,0-14-6.3-14-14v-6.3c0-7.7,6.3-14,14-14h326.8c7.7,0,14,6.3,14,14v6.3
|
||||
C435.4,206.7,429.1,213,421.4,213z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><style>.st0{display:none}.st1{display:inline}.st2{fill:#0071bc}.st3{display:inline}.st3,.st4{fill:#fff}</style><path class="st0 st1 st2" d="M1 444V68c1.3-5.1 2.3-10.3 3.9-15.4C15.5 20.1 43.9.1 79.4.1h355.2c2.3 0 4.7 0 7 .2 29 2.6 50.7 16.4 63.5 42.7 3.8 7.8 5.3 16.6 7.9 25v376c-.4 1.1-.9 2.1-1 3.2-4.4 26.1-18.2 45.4-42 56.9-7.8 3.7-16.6 5.3-24.9 7.9h-376c-1.1-.4-2.1-.9-3.2-1-26.1-4.4-45.4-18.2-56.9-42-3.8-7.8-5.4-16.7-8-25z" id="Ebene_2"/><path class="st0 st1" d="M1-18.8h511V512H1z" id="Ebene_4"/><g id="Ebene_1" class="st0"><path class="st3" d="M164 144H81c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM164 244.3H81c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM164 344.6H81c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM164 444H81c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM433 144h-83c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM433 244.3h-83c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM433 344.6h-83c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM297.5 144h-83c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12zM297.5 244.3h-83c-6.6 0-12-5.4-12-12v-52c0-6.6 5.4-12 12-12h83c6.6 0 12 5.4 12 12v52c0 6.6-5.4 12-12 12z"/></g><g id="Ebene_3"><path class="st4" d="M432.3 448.1h-348c-13.2 0-24-10.8-24-24V264.6c0-13.2 10.8-24 24-24h348c13.2 0 24 10.8 24 24v159.5c0 13.2-10.8 24-24 24zM380.4 89.8H127.8c-7.7 0-14-6.3-14-14v-6.3c0-7.7 6.3-14 14-14h252.6c7.7 0 14 6.3 14 14v6.3c0 7.7-6.3 14-14 14zM399.8 151.6H110.6c-7.7 0-14-6.3-14-14v-6.3c0-7.7 6.3-14 14-14h289.2c7.7 0 14 6.3 14 14v6.3c0 7.7-6.3 14-14 14zM421.4 213H94.6c-7.7 0-14-6.3-14-14v-6.3c0-7.7 6.3-14 14-14h326.8c7.7 0 14 6.3 14 14v6.3c0 7.7-6.3 14-14 14z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -61,6 +61,7 @@ class BoardController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @RequireNoPermission
|
||||
*/
|
||||
public function index() {
|
||||
return $this->boardService->findAll($this->userInfo);
|
||||
@@ -76,6 +77,7 @@ class BoardController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @RequireNoPermission
|
||||
*/
|
||||
public function create($title, $color) {
|
||||
return $this->boardService->create($title, $this->userId, $color);
|
||||
@@ -102,7 +104,7 @@ class BoardController extends Controller {
|
||||
* @RequireReadPermission
|
||||
*/
|
||||
public function labels($boardId) {
|
||||
return $this->boardService->labels($this->boardId);
|
||||
return $this->boardService->labels($boardId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,11 @@ use JsonSerializable;
|
||||
|
||||
class Acl extends Entity implements JsonSerializable {
|
||||
|
||||
const PERMISSION_READ = 0;
|
||||
const PERMISSION_EDIT = 1;
|
||||
const PERMISSION_SHARE = 2;
|
||||
const PERMISSION_MANAGE = 3;
|
||||
|
||||
public $id;
|
||||
protected $participant;
|
||||
protected $type;
|
||||
@@ -46,6 +51,21 @@ class Acl extends Entity implements JsonSerializable {
|
||||
$this->addType('owner', 'boolean');
|
||||
$this->addRelation('owner');
|
||||
}
|
||||
|
||||
public function getPermission($permission) {
|
||||
switch ($permission) {
|
||||
case Acl::PERMISSION_READ:
|
||||
return true;
|
||||
case Acl::PERMISSION_EDIT:
|
||||
return $this->getPermissionWrite();
|
||||
case Acl::PERMISSION_SHARE:
|
||||
return $this->getPermissionInvite();
|
||||
case Acl::PERMISSION_MANAGE:
|
||||
return $this->getPermissionManage();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function jsonSerialize() {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
|
||||
@@ -41,20 +41,6 @@ class AclMapper extends DeckMapper implements IPermissionMapper {
|
||||
return $this->findEntities($sql, [$boardId], $limit, $offset);
|
||||
}
|
||||
|
||||
public function findAllShared($boardId) {
|
||||
$sql = 'SELECT id, board_id, type, participant, permission_write, permission_invite, permission_manage FROM `*PREFIX*deck_board_acl` WHERE `board_id` = ? ';
|
||||
return $this->findEntities($sql, [$boardId]);
|
||||
}
|
||||
public function findAllForCard($cardId, $userId) {
|
||||
$findBoardId = "(SELECT board_id from oc_deck_stacks WHERE id IN (SELECT stack_id from oc_deck_cards WHERE id = 15))";
|
||||
$sql = "SELECT 0, id, 'user', owner, 1, 1, 1, 1 as owner FROM `oc_deck_boards` " .
|
||||
"WHERE `id` IN (SELECT board_id from oc_deck_stacks WHERE id IN (SELECT stack_id from oc_deck_cards WHERE id = 15))
|
||||
UNION
|
||||
SELECT id, board_id, type, participant, permission_write, permission_invite, permission_manage, 0 FROM oc_deck_board_acl
|
||||
WHERE participant = 'admin' AND board_id IN (SELECT board_id from oc_deck_stacks WHERE id IN (SELECT stack_id from oc_deck_cards WHERE id = 15));";
|
||||
|
||||
}
|
||||
|
||||
public function isOwner($userId, $aclId) {
|
||||
$sql = 'SELECT * FROM `*PREFIX*deck_boards` WHERE `id` IN (SELECT board_id FROM `*PREFIX*deck_board_acl` WHERE id = ?)';
|
||||
$stmt = $this->execute($sql, [$aclId]);
|
||||
|
||||
@@ -28,7 +28,7 @@ use OCP\AppFramework\Db\Mapper;
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
|
||||
|
||||
class BoardMapper extends Mapper implements IPermissionMapper {
|
||||
class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
|
||||
private $labelMapper;
|
||||
private $_relationMappers = array();
|
||||
|
||||
@@ -49,4 +49,11 @@ abstract class DeckMapper extends Mapper {
|
||||
|
||||
}
|
||||
|
||||
protected function execute($sql, array $params = [], $limit = null, $offset = null) {
|
||||
|
||||
\OCP\Util::writeLog('deck', "SQL: " . $sql, \OCP\Util::DEBUG);
|
||||
|
||||
return parent::execute($sql, $params, $limit, $offset); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,20 +21,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: jus
|
||||
* Date: 19.08.16
|
||||
* Time: 22:25
|
||||
*/
|
||||
|
||||
namespace OCA\Deck\Db;
|
||||
|
||||
|
||||
interface IPermissionMapper {
|
||||
|
||||
/**
|
||||
* Check if $userId is owner of Entity with $id
|
||||
*
|
||||
* @param $userId string userId
|
||||
* @param $id int|string unique entity identifier
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOwner($userId, $id);
|
||||
|
||||
/**
|
||||
* Query boardId for Entity of given $id
|
||||
*
|
||||
* @param $id int|string unique entity identifier
|
||||
* @return int|null id of Board
|
||||
*/
|
||||
public function findBoardId($id);
|
||||
|
||||
|
||||
|
||||
@@ -5,45 +5,38 @@
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Deck\Middleware;
|
||||
|
||||
use OC\OCS\Exception;
|
||||
use OCA\Deck\Controller\BoardController;
|
||||
use OCA\Deck\Controller\CardController;
|
||||
use OCA\Deck\Controller\LabelController;
|
||||
use OCA\Deck\Controller\PageController;
|
||||
use OCA\Deck\Controller\ShareController;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\NoPermissionException;
|
||||
use OCA\Deck\Service\ServicePermissionException;
|
||||
use OCA\Files_Versions\Expiration;
|
||||
use \OCP\AppFramework\Middleware;
|
||||
use OCP\IContainer;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserManager;
|
||||
use OCA\Deck\Controller\StackController;
|
||||
use OCP\IUserSession;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
|
||||
use OCA\Deck\Db\Acl;
|
||||
|
||||
class SharingMiddleware extends Middleware {
|
||||
|
||||
@@ -52,6 +45,8 @@ class SharingMiddleware extends Middleware {
|
||||
private $userSession;
|
||||
private $reflector;
|
||||
private $groupManager;
|
||||
private $aclMapper;
|
||||
|
||||
|
||||
public function __construct(
|
||||
IContainer $container,
|
||||
@@ -65,17 +60,17 @@ class SharingMiddleware extends Middleware {
|
||||
$this->reflector = $reflector;
|
||||
$this->aclMapper = $this->container->query('OCA\Deck\Db\AclMapper');
|
||||
$this->groupManager = $this->container->query('\OCP\IGroupManager');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* All permission checks for controller access
|
||||
*
|
||||
* The following method annotaitons are possible
|
||||
* The following method annotations are possible
|
||||
* - RequireReadPermission
|
||||
* - RequireEditPermission
|
||||
* - RequireSharePermission
|
||||
* - RequireManagePermission
|
||||
* - RequireNoPermission
|
||||
*
|
||||
* Depending on the Controller class we call a corresponding mapper to find the board_id
|
||||
* With the board_id we can check for ownership/permissions in the acl table
|
||||
@@ -85,35 +80,50 @@ class SharingMiddleware extends Middleware {
|
||||
* @throws NoPermissionException
|
||||
*/
|
||||
public function beforeController($controller, $methodName) {
|
||||
$this->start = microtime(true);
|
||||
|
||||
$userId = null;
|
||||
if($this->userSession->getUser()) {
|
||||
if ($this->userSession->getUser()) {
|
||||
$userId = $this->userSession->getUser()->getUID();
|
||||
}
|
||||
$method = $this->request->getMethod();
|
||||
$params = $this->request->getParams();
|
||||
$this->checkPermissions($userId, $controller, $method, $params);
|
||||
|
||||
// TODO: remove, just for testing
|
||||
\OCP\Util::writeLog('deck', (microtime(true)-$this->start), \OCP\Util::ERROR);
|
||||
$this->checkPermissions($userId, $controller, $method, $params, $methodName);
|
||||
|
||||
}
|
||||
|
||||
private function checkPermissions($userId, $controller, $method, $params) {
|
||||
/**
|
||||
* Check permission depending on the route (controller/method)
|
||||
*
|
||||
* @param $userId
|
||||
* @param $controller
|
||||
* @param $method
|
||||
* @param $params
|
||||
* @param $methodName
|
||||
* @return bool
|
||||
* @throws NoPermissionException
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function checkPermissions($userId, $controller, $method, $params, $methodName) {
|
||||
|
||||
// no permission checks needed for plain html page
|
||||
if($controller instanceof PageController) {
|
||||
return;
|
||||
// no permission checks needed for plain html page or RequireNoPermission
|
||||
if (
|
||||
$controller instanceof PageController ||
|
||||
$this->reflector->hasAnnotation('RequireNoPermission')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$mapper = null;
|
||||
$id = null;
|
||||
|
||||
// FIXME: ShareController#search should be limited to board users/groups
|
||||
if($controller instanceof BoardController or $controller instanceof ShareController) {
|
||||
if ($controller instanceof BoardController or $controller instanceof ShareController) {
|
||||
$mapper = $this->container->query('OCA\Deck\Db\BoardMapper');
|
||||
$id = $params['boardId'];
|
||||
}
|
||||
|
||||
if($controller instanceof StackController) {
|
||||
if($method==="GET" || $method === "POST") {
|
||||
if ($controller instanceof StackController) {
|
||||
if ($method === "GET" || $method === "POST") {
|
||||
$mapper = $this->container->query('OCA\Deck\Db\BoardMapper');
|
||||
$id = $params['boardId'];
|
||||
} else {
|
||||
@@ -122,8 +132,8 @@ class SharingMiddleware extends Middleware {
|
||||
}
|
||||
|
||||
}
|
||||
if($controller instanceof CardController) {
|
||||
if($method === "POST" && !preg_match('/Label/', $method)) {
|
||||
if ($controller instanceof CardController) {
|
||||
if ($method === "POST" && !preg_match('/Label/', $method)) {
|
||||
$mapper = $this->container->query('OCA\Deck\Db\StackMapper');
|
||||
$id = $params['stackId'];
|
||||
} else {
|
||||
@@ -132,144 +142,91 @@ class SharingMiddleware extends Middleware {
|
||||
}
|
||||
|
||||
}
|
||||
if($controller instanceof LabelController) {
|
||||
if($method==="GET" || $method === "POST") {
|
||||
if ($controller instanceof LabelController) {
|
||||
if ($method === "GET" || $method === "POST") {
|
||||
$mapper = $this->container->query('OCA\Deck\Db\BoardMapper');
|
||||
$id = $params['boardId'];
|
||||
} else {
|
||||
$mapper = $this->container->query('OCA\Deck\Db\LabelMapper');
|
||||
$id = $params['labelId'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check if there is a mapper so we can find the corresponding board for the request
|
||||
if ($mapper === null) {
|
||||
throw new \Exception("No mappers specified for permission checks");
|
||||
}
|
||||
|
||||
if($this->reflector->hasAnnotation('RequireReadPermission')) {
|
||||
if(!$this->checkReadPermission($userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User ". $userId . " has no permission to read.", $controller, $method);
|
||||
if ($this->reflector->hasAnnotation('RequireReadPermission')) {
|
||||
if (!$this->checkMapperPermission(Acl::PERMISSION_READ, $userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User " . $userId . " has no permission to read.", $controller, $methodName);
|
||||
}
|
||||
}
|
||||
if($this->reflector->hasAnnotation('RequireEditPermission')) {
|
||||
if(!$this->checkEditPermission($userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User ". $userId . " has no permission to edit.", $controller, $method);
|
||||
}
|
||||
|
||||
}
|
||||
if($this->reflector->hasAnnotation('RequireSharePermission')) {
|
||||
if(!$this->checkSharePermission($userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User ". $userId . " has no permission to share.", $controller, $method);
|
||||
if ($this->reflector->hasAnnotation('RequireEditPermission')) {
|
||||
if (!$this->checkMapperPermission(Acl::PERMISSION_EDIT, $userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User " . $userId . " has no permission to edit.", $controller, $methodName);
|
||||
}
|
||||
}
|
||||
if($this->reflector->hasAnnotation('RequireManagePermission')) {
|
||||
if(!$this->checkManagePermission($userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User ". $userId . " has no permission to manage.", $controller, $method);
|
||||
if ($this->reflector->hasAnnotation('RequireSharePermission')) {
|
||||
if (!$this->checkMapperPermission(Acl::PERMISSION_SHARE, $userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User " . $userId . " has no permission to share.", $controller, $methodName);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Default should be nopermisison mybe add norequirepermission for index
|
||||
if ($this->reflector->hasAnnotation('RequireManagePermission')) {
|
||||
if (!$this->checkMapperPermission(Acl::PERMISSION_MANAGE, $userId, $mapper, $id)) {
|
||||
throw new NoPermissionException("User " . $userId . " has no permission to manage.", $controller, $methodName);
|
||||
}
|
||||
}
|
||||
// all permission checks succeeded
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/* TODO: Priorize groups with higher permissions */
|
||||
public function checkReadPermission($userId, $mapper, $id) {
|
||||
// is owner
|
||||
if($mapper->isOwner($userId, $id)) {
|
||||
return true;
|
||||
}
|
||||
$boardId = $mapper->findBoardId($id);
|
||||
$acls = $this->aclMapper->findAllShared($boardId);
|
||||
// check for users
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $acl->getParticipant() === $userId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// check for groups
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $this->groupManager->isInGroup($userId, $acl->getParticipant())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check if $userId is authorized for $permission on board related to $mapper with $id
|
||||
*
|
||||
* @param $permission
|
||||
* @param $userId
|
||||
* @param $mapper
|
||||
* @param $id
|
||||
* @return bool
|
||||
*/
|
||||
public function checkMapperPermission($permission, $userId, $mapper, $id) {
|
||||
|
||||
throw new NoPermissionException("User ". $userId . " has no permission to read.");
|
||||
|
||||
}
|
||||
public function checkEditPermission($userId, $mapper, $id) {
|
||||
// is owner
|
||||
if($mapper->isOwner($userId, $id)) {
|
||||
if ($mapper->isOwner($userId, $id)) {
|
||||
return true;
|
||||
}
|
||||
// check if is in acl
|
||||
$boardId = $mapper->findBoardId($id);
|
||||
$acls = $this->aclMapper->findAllShared($boardId);
|
||||
$acls = $this->aclMapper->findAll($boardId);
|
||||
// check for users
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $acl->getParticipant() === $userId) {
|
||||
return $acl->getPermissionWrite();
|
||||
if ($acl->getType() === "user" && $acl->getParticipant() === $userId) {
|
||||
return $acl->getPermission($permission);
|
||||
}
|
||||
}
|
||||
// check for groups
|
||||
$hasGroupPermission = false;
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $this->groupManager->isInGroup($userId, $acl->getParticipant())) {
|
||||
return $acl->getPermissionWrite();
|
||||
if (!$hasGroupPermission && $acl->getType() === "group" && $this->groupManager->isInGroup($userId, $acl->getParticipant())) {
|
||||
$hasGroupPermission = $acl->getPermission($permission);
|
||||
}
|
||||
}
|
||||
|
||||
throw new NoPermissionException("User ". $userId . " has no permission to edit.");
|
||||
|
||||
}
|
||||
public function checkManagePermission($userId, $mapper, $id) {
|
||||
// is owner
|
||||
if($mapper->isOwner($userId, $id)) {
|
||||
return true;
|
||||
}
|
||||
// check if is in acl
|
||||
$boardId = $mapper->findBoardId($id);
|
||||
$acls = $this->aclMapper->findAllShared($boardId);
|
||||
// check for users
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $acl->getParticipant() === $userId) {
|
||||
return $acl->getPermissionManage();
|
||||
}
|
||||
}
|
||||
// check for groups
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $this->groupManager->isInGroup($userId, $acl->getParticipant())) {
|
||||
return $acl->getPermissionManage();
|
||||
}
|
||||
}
|
||||
|
||||
throw new NoPermissionException();
|
||||
|
||||
}
|
||||
public function checkSharePermission($userId, $mapper, $id) {
|
||||
// is owner
|
||||
if($mapper->isOwner($userId, $id)) {
|
||||
return true;
|
||||
}
|
||||
// check if is in acl
|
||||
$boardId = $mapper->findBoardId($id);
|
||||
$acls = $this->aclMapper->findAllShared($boardId);
|
||||
// check for users
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $acl->getParticipant() === $userId) {
|
||||
return $acl->getPermissionInvite();
|
||||
}
|
||||
}
|
||||
// check for groups
|
||||
foreach ($acls as $acl) {
|
||||
if($acl->getType() === "user" && $this->groupManager->isInGroup($userId, $acl->getParticipant())) {
|
||||
return $acl->getPermissionInvite();
|
||||
}
|
||||
}
|
||||
|
||||
throw new NoPermissionException();
|
||||
|
||||
return $hasGroupPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return JSON error response if the user has no sufficient permission
|
||||
*
|
||||
* @param \OCP\AppFramework\Controller $controller
|
||||
* @param string $methodName
|
||||
* @param \Exception $exception
|
||||
* @return JSONResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function afterException($controller, $methodName, \Exception $exception) {
|
||||
\OCP\Util::writeLog('deck', (microtime(true)-$this->start), \OCP\Util::ERROR);
|
||||
if(is_a($exception, '\OCA\Deck\NoPermissionException')) {
|
||||
if (is_a($exception, '\OCA\Deck\NoPermissionException')) {
|
||||
return new JSONResponse([
|
||||
"status" => 401,
|
||||
"message" => $exception->getMessage()
|
||||
|
||||
@@ -5,29 +5,27 @@
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
use OCP\Util;
|
||||
|
||||
Util::addStyle('deck', 'font-awesome');
|
||||
Util::addStyle('deck', 'style');
|
||||
Util::addStyle('deck', '../js/vendor/ng-sortable/dist/ng-sortable.min');
|
||||
Util::addStyle('deck', '../js/vendor/angular-ui-select/dist/select.min');
|
||||
//Util::addStyle('deck', '../js/vendor/ng-sortable/dist/ng-sortable.style.min');
|
||||
Util::addScript('deck', 'vendor/angular/angular.min');
|
||||
Util::addScript('deck', 'vendor/angular-route/angular-route.min');
|
||||
Util::addScript('deck', 'vendor/angular-sanitize/angular-sanitize.min');
|
||||
@@ -44,20 +42,18 @@ Util::addScript('deck', 'public/app');
|
||||
|
||||
<div id="app-navigation" data-ng-controller="ListController">
|
||||
<?php print_unescaped($this->inc('part.navigation')); ?>
|
||||
<?php print_unescaped($this->inc('part.settings')); ?>
|
||||
<?php /* print_unescaped($this->inc('part.settings'));*/ ?>
|
||||
</div>
|
||||
<div id="app-content" ng-class="{ 'details-visible': sidebar.show }">
|
||||
<div id="app-view" ui-view></div>
|
||||
<div id="app-content" ng-class="{ 'details-visible': sidebar.show }">
|
||||
<div id="app-view" ui-view></div>
|
||||
</div>
|
||||
<route-loading-indicator />
|
||||
<route-loading-indicator></route-loading-indicator>
|
||||
|
||||
|
||||
<script type="text/ng-template" id="/boardlist.mainView.html">
|
||||
<?php print_unescaped($this->inc('part.boardlist')); ?>
|
||||
</script>
|
||||
<script type="text/ng-template" id="/boardlist.sidebarView.html">
|
||||
<?php print_unescaped($this->inc('part.empty')); ?>
|
||||
</script>
|
||||
<script type="text/ng-template" id="/boardlist.sidebarView.html"></script>
|
||||
<script type="text/ng-template" id="/board.sidebarView.html">
|
||||
<?php print_unescaped($this->inc('part.board.sidebarView')); ?>
|
||||
</script>
|
||||
@@ -71,5 +67,4 @@ Util::addScript('deck', 'public/app');
|
||||
<?php print_unescaped($this->inc('part.card')); ?>
|
||||
</script>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<p>{{ statusservice.text }}</p></div>
|
||||
</div>
|
||||
<div id="board-header"
|
||||
style="background-color: {{boardservice.getCurrent().color | lightenColorFilter }}; color: {{boardservice.getCurrent().color | textColorFilter }};">
|
||||
style="background-color: #{{boardservice.getCurrent().color }}; color: {{boardservice.getCurrent().color | textColorFilter }};">
|
||||
<h1>
|
||||
{{ boardservice.data[id].title }}
|
||||
<div id="board-actions">
|
||||
@@ -30,11 +30,12 @@
|
||||
ng-blur="s.status.editStack=false" ng-model="s.title"
|
||||
ng-if="s.status.editStack" autofocus-on-insert
|
||||
required/>
|
||||
<button class="icon icon-save" ng-if="s.status.editStack"
|
||||
type="submit"></button>
|
||||
|
||||
</form>
|
||||
<div class="stack-actions">
|
||||
<button class="icon-rename"
|
||||
<button class="icon icon-confirm" ng-if="s.status.editStack"
|
||||
type="submit"></button>
|
||||
<button class="icon-rename" ng-if="!s.status.editStack"
|
||||
ng-click="s.status.editStack=true"></button>
|
||||
<button class="icon-delete"
|
||||
ng-click="stackservice.delete(s.id)"></button>
|
||||
@@ -105,8 +106,9 @@
|
||||
ng-blur="s.status.addCard=false" required/>
|
||||
</h3>
|
||||
</form>
|
||||
<div class="icon icon-add" ng-if="!s.status.addCard"
|
||||
ng-click="s.status.addCard=!s.status.addCard"></div>
|
||||
<div ng-if="!s.status.addCard" ng-click="s.status.addCard=!s.status.addCard">
|
||||
<i class="icon icon-add"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stack" style="display: inline-block;" ng-if="checkCanEdit()">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
<?php print_unescaped($this->inc('part.board.mainView')); ?>
|
||||
<div id="app-sidebar" class="details-view scroll-container" ng-class="{ 'details-visible': sidebar.show }" ui-view="sidebarView">
|
||||
</div>
|
||||
<?php print_unescaped($this->inc('part.board.mainView')); ?>
|
||||
<div id="app-sidebar" class="details-view scroll-container"
|
||||
ng-class="{ 'details-visible': sidebar.show }" ui-view="sidebarView">
|
||||
</div>
|
||||
|
||||