Skip to content

Commit a183a1d

Browse files
authored
Merge pull request #20 from qh4r/packages/react-router-authorization-implementation
Added implementation for react-router-permissions
2 parents f5974e9 + 6dce4c1 commit a183a1d

File tree

25 files changed

+777
-3923
lines changed

25 files changed

+777
-3923
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ coverage
44
npm-debug.log*
55
yarn-debug.log*
66
yarn-error.log*
7-
lerna-debug.log
7+
lerna-debug.log

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ That means that [several packages](/packages) are published to npm from the same
1111
| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
1212
| [`react-json-translation-provider`](/packages/react-json-translation-provider) | ![version](https://img.shields.io/npm/v/@tshio/react-json-translation-provider.svg) | JSON files translation provider to [react-intl](https://github.com/yahoo/react-intl) |
1313
| [`react-router-pagination`](/packages/react-router-pagination) | ![version](https://img.shields.io/npm/v/@tshio/react-router-pagination.svg) | HOC to connect [react-router](https://github.com/ReactTraining/react-router) with custom pagination component |
14+
| [`react-router-permissions`](/packages/react-router-permissions) | ![version](https://img.shields.io/npm/v/@tshio/react-router-permissions.svg) | Toolkit for authorization management, contains [react-router](https://github.com/ReactTraining/react-router) | extension |
1415
| [`redux-api-auth-middleware`](/packages/redux-api-auth-middleware) | ![version](https://img.shields.io/npm/v/@tshio/redux-api-auth-middleware.svg) | Authorization middleware to [redux-api-middleware](https://github.com/agraboso/redux-api-middleware) |
1516
| [`redux-api-content-middleware`](/packages/redux-api-content-middleware) | ![version](https://img.shields.io/npm/v/@tshio/redux-api-content-middleware.svg) | Adding JSON body support middleware to [redux-api-middleware](https://github.com/agraboso/redux-api-middleware) |
1617
| [`redux-api-endpoint-middleware`](/packages/redux-api-endpoint-middleware) | ![version](https://img.shields.io/npm/v/@tshio/redux-api-endpoint-middleware.svg) | Endpoint prefixing middleware to [redux-api-middleware](https://github.com/agraboso/redux-api-middleware) |
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// flow-typed signature: ea482fb27a1352860e93a861681ae6e9
2+
// flow-typed version: 01716df816/react-router_v4.x.x/flow_>=v0.53.x
3+
4+
declare module "react-router" {
5+
// NOTE: many of these are re-exported by react-router-dom and
6+
// react-router-native, so when making changes, please be sure to update those
7+
// as well.
8+
declare export type Location = {
9+
pathname: string,
10+
search: string,
11+
hash: string,
12+
state?: any,
13+
key?: string
14+
};
15+
16+
declare export type LocationShape = {
17+
pathname?: string,
18+
search?: string,
19+
hash?: string,
20+
state?: any
21+
};
22+
23+
declare export type HistoryAction = "PUSH" | "REPLACE" | "POP";
24+
25+
declare export type RouterHistory = {
26+
length: number,
27+
location: Location,
28+
action: HistoryAction,
29+
listen(
30+
callback: (location: Location, action: HistoryAction) => void
31+
): () => void,
32+
push(path: string | LocationShape, state?: any): void,
33+
replace(path: string | LocationShape, state?: any): void,
34+
go(n: number): void,
35+
goBack(): void,
36+
goForward(): void,
37+
canGo?: (n: number) => boolean,
38+
block(
39+
callback: (location: Location, action: HistoryAction) => boolean
40+
): void,
41+
// createMemoryHistory
42+
index?: number,
43+
entries?: Array<Location>
44+
};
45+
46+
declare export type Match = {
47+
params: { [key: string]: ?string },
48+
isExact: boolean,
49+
path: string,
50+
url: string
51+
};
52+
53+
declare export type ContextRouter = {|
54+
history: RouterHistory,
55+
location: Location,
56+
match: Match
57+
|};
58+
59+
declare export type GetUserConfirmation = (
60+
message: string,
61+
callback: (confirmed: boolean) => void
62+
) => void;
63+
64+
declare type StaticRouterContext = {
65+
url?: string
66+
};
67+
68+
declare export class StaticRouter extends React$Component<{
69+
basename?: string,
70+
location?: string | Location,
71+
context: StaticRouterContext,
72+
children?: React$Node
73+
}> {}
74+
75+
declare export class MemoryRouter extends React$Component<{
76+
initialEntries?: Array<LocationShape | string>,
77+
initialIndex?: number,
78+
getUserConfirmation?: GetUserConfirmation,
79+
keyLength?: number,
80+
children?: React$Node
81+
}> {}
82+
83+
declare export class Router extends React$Component<{
84+
history: RouterHistory,
85+
children?: React$Node
86+
}> {}
87+
88+
declare export class Prompt extends React$Component<{
89+
message: string | ((location: Location) => string | true),
90+
when?: boolean
91+
}> {}
92+
93+
declare export class Redirect extends React$Component<{
94+
to: string | LocationShape,
95+
push?: boolean
96+
}> {}
97+
98+
declare export class Route extends React$Component<{
99+
component?: React$ComponentType<*>,
100+
render?: (router: ContextRouter) => React$Node,
101+
children?: React$ComponentType<ContextRouter> | React$Node,
102+
path?: string,
103+
exact?: boolean,
104+
strict?: boolean
105+
}> {}
106+
107+
declare export class Switch extends React$Component<{
108+
children?: React$Node
109+
}> {}
110+
111+
declare export function withRouter<P>(
112+
Component: React$ComponentType<{| ...ContextRouter, ...P |}>
113+
): React$ComponentType<P>;
114+
115+
declare type MatchPathOptions = {
116+
path?: string,
117+
exact?: boolean,
118+
strict?: boolean,
119+
sensitive?: boolean
120+
};
121+
declare export function matchPath(
122+
pathname: string,
123+
options?: MatchPathOptions | string
124+
): null | Match;
125+
}

packages/react-router-pagination/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
},
2222
"peerDependencies": {
2323
"react": ">=16.5.2",
24+
"react-router": "^4.3.1",
2425
"react-router-dom": ">=4.3.1"
2526
},
2627
"devDependencies": {

packages/react-router-pagination/src/react-router-pagination.types.js.flow

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// @flow
2-
import type { Location, RouterHistory } from 'react-router-dom';
2+
import type { Location, RouterHistory } from 'react-router';
33

44
export type ConfigOptions = {
55
currentPageKey: string,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-flow",
5+
"@babel/preset-react"
6+
],
7+
"plugins": [
8+
"@babel/plugin-proposal-class-properties",
9+
"@babel/plugin-proposal-export-default-from"
10+
]
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[ignore]
2+
3+
[include]
4+
5+
[libs]
6+
7+
[lints]
8+
9+
[options]
10+
11+
[strict]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
es
2+
/*.js
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 The Software House Sp. z o.o.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/react-router-permissions/README.md

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,82 @@ const authorizationStrategy = (permissions, requirement) => {
9898
>
9999
```
100100

101-
There will be some strategies provided with the package out of the box. Role based and Permissions based strategies will be included.
101+
There are some strategies provided with the package out of the box. Those are:
102+
103+
- Role based strategy
104+
105+
```js
106+
const permissions = ['MODERATOR', 'PREMIUM_USER'];
107+
108+
...
109+
// authorization will pass
110+
<AuthorizedRoute
111+
path='/authorized-section'
112+
requires='MODERATOR'
113+
>
114+
...
115+
116+
...
117+
// authorization will fail
118+
<AuthorizedRoute
119+
path='/authorized-section'
120+
requires='ADMIN'
121+
>
122+
...
123+
```
124+
125+
* Permissions based strategy
126+
127+
```js
128+
const permissions = {
129+
canReadPosts: true,
130+
canManagePosts: true,
131+
canManageUsers: false,
132+
};
133+
134+
...
135+
// authorization will pass
136+
<AuthorizedRoute
137+
path='/authorized-section'
138+
requires='canManagePosts'
139+
>
140+
...
141+
142+
...
143+
// authorization will fail
144+
<AuthorizedRoute
145+
path='/authorized-section'
146+
requires='canManageUsers'
147+
>
148+
...
149+
```
150+
151+
* At least one strategy
152+
153+
```js
154+
const permissions = {
155+
canReadPosts: true,
156+
canManagePosts: false,
157+
canManageUsers: false,
158+
canViewUsers: false,
159+
};
160+
161+
...
162+
// authorization will pass
163+
<AuthorizedRoute
164+
path='/authorized-section'
165+
requires={['canReadPosts', 'canManagePosts']}
166+
>
167+
...
168+
169+
...
170+
// authorization will fail
171+
<AuthorizedRoute
172+
path='/authorized-section'
173+
requires={['canManageUsers', 'canViewUsers']}
174+
>
175+
...
176+
```
102177

103178
We also provide authorized section to cover cases where we need authorization but want to be route agnostic
104179

@@ -122,7 +197,7 @@ This works exactly like AuthorizedRoute but will attempt access regardless of ac
122197
Since permissions are being fetched from context, it is possible to override them for certain section of our application
123198
using nested `PermissionsProvider`. Result of `authorizationStrategy` does not need to be boolean too.
124199
While most of the time it being a boolean might be convenient. It is possible for `authorizationStrategy`
125-
to return complex object that we can utilize in our component
200+
to return complex object that we can utilize in our component.
126201

127202
```js
128203
const store = createStore(

0 commit comments

Comments
 (0)