Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/access control #49

Merged
merged 56 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
3755377
force menu right 6 and bottom 0
dataontabs May 3, 2022
99c714e
change project to typescript; redux; sagas; ant design
dataontabs May 25, 2022
b519aff
refactoring peers layout
dataontabs May 26, 2022
725cc74
setup keys list; setup key new; setup key revoke;
dataontabs May 27, 2022
4701c20
add peer; create tabs components, create steps components;
dataontabs May 28, 2022
038ee6c
access control and activity screen
dataontabs May 28, 2022
1b83954
Merge branch 'main' into feature/access-control
dataontabs May 28, 2022
40636fe
fix setup key filter; remove old files js;
dataontabs May 28, 2022
f7f40d3
users list
dataontabs May 28, 2022
6fa0939
list users; set tables pagination showSizeChanger to false
dataontabs May 28, 2022
306fea6
add user menu and user menu responsive; add loading on all pages
dataontabs May 28, 2022
3e70556
[fix] If I click the Add Peer button on the Peers list the page doesn…
dataontabs May 28, 2022
956765f
[fix] buttonCopyMessage key
dataontabs May 28, 2022
011ad3d
rules store
dataontabs May 28, 2022
8af69ac
rules store
dataontabs May 28, 2022
2a5f716
Append management URL on netbird up command if self-hosted
braginini May 29, 2022
93487e4
add/update/delete rule; show tutorial; tags controller; show modal gr…
dataontabs May 30, 2022
8846991
Merge branch 'feature/access-control' of github.com:netbirdio/dashboa…
dataontabs May 30, 2022
77a9ecd
change rule input name
dataontabs May 30, 2022
e03c996
select tags with peers count
dataontabs May 30, 2022
c32c944
access control show groups on popover
dataontabs May 30, 2022
4434f4f
fix learn more access control link new rule
dataontabs May 30, 2022
ee082cc
group routes to peers
dataontabs Jun 1, 2022
df3a4a9
group routes to peers
dataontabs Jun 1, 2022
ea7037c
Merge branch 'main' into feature/access-control
dataontabs Jun 1, 2022
3737c10
show acl menu
dataontabs Jun 1, 2022
745558a
Merge branch 'feature/access-control' of github.com:netbirdio/dashboa…
dataontabs Jun 1, 2022
460195e
add groups on peers; fix alerts on save; description and disabled on …
dataontabs Jun 9, 2022
ae4c342
add groups on peers; fix alerts on save; description and disabled on …
dataontabs Jun 9, 2022
450f5a4
add groups on peers; fix alerts on save; description and disabled on …
dataontabs Jun 9, 2022
21bec02
Merge branch 'feature/access-control' of github.com:netbirdio/dashboa…
dataontabs Jun 9, 2022
265d3c3
Merge branch 'main' into feature/access-control
dataontabs Jun 9, 2022
f67893d
filter enabled rules
dataontabs Jun 9, 2022
8b069c6
hide activity view
dataontabs Jun 9, 2022
3ec765b
fix interface props
dataontabs Jun 9, 2022
595960d
add column descriprion and status on AccessControl list
dataontabs Jun 9, 2022
158aa4f
Groups could be placed after Status Column; Description should be too…
dataontabs Jun 10, 2022
ccea6f2
When creating a new group, is possible to display a message that indi…
dataontabs Jun 10, 2022
a237d61
Singular only peers count equals 1
mlsmaycon Jun 11, 2022
c4db43f
Correct wording for peers and rules popups
braginini Jun 11, 2022
2a76131
Add Table Spin
braginini Jun 11, 2022
0fa4c88
disable button save groups while is any no change
dataontabs Jun 11, 2022
0d939ed
Fix user view to reflect API changes
braginini Jun 12, 2022
87d31da
Sync API payload fields case for peers
mlsmaycon Jun 13, 2022
43be501
Sync API payload fields case for users
mlsmaycon Jun 13, 2022
6db970a
Sync API payload fields case for setup keys
mlsmaycon Jun 13, 2022
279736e
Sync API payload fields case for rules
mlsmaycon Jun 13, 2022
d43c1b6
remove warning and search case
mlsmaycon Jun 13, 2022
85b410c
fix filter acls
dataontabs Jun 13, 2022
2522e37
Remove access control image
braginini Jun 14, 2022
d71938c
Add default sorting by name
braginini Jun 14, 2022
3b3315c
Set proper links for ACL docs
braginini Jun 14, 2022
63b70f4
Edit rule on click over name or Srcs and Dests
mlsmaycon Jun 14, 2022
56dc7e0
Sorrt by name using table property
mlsmaycon Jun 15, 2022
d01fa82
Move all button to the right
mlsmaycon Jun 15, 2022
4ef8da8
use icon if avatar image is not available
mlsmaycon Jun 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Loading from "./components/Loading";
import SetupKeys from "./views/SetupKeys";
import AddPeer from "./views/AddPeer";
import Users from './views/Users';
import AccessControl from './views/AccessControl';
// import Activity from './views/Activity';
import Banner from "./components/Banner";
import {store} from "./store";

Expand Down Expand Up @@ -111,8 +113,8 @@ function App() {
<Route path='/peers' exact component={Peers}/>
<Route path="/add-peer" component={AddPeer}/>
<Route path="/setup-keys" component={SetupKeys}/>
{/*<Route path="/acls" component={AccessControl}/>
<Route path="/activity" component={Activity}/>*/}
<Route path="/acls" component={AccessControl}/>
{/*<Route path="/activity" component={Activity}/>*/}
<Route path="/users" component={Users}/>
</Switch>
</Content>
Expand Down
6 changes: 3 additions & 3 deletions src/components/AccessControlModalGroups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const AccessControlModalGroups:React.FC<Props> = ({data, title, visible, onCance
renderItem={(item:Group) => (
<List.Item>
<List.Item.Meta
avatar={<Avatar>{item.Name.slice(0,1).toUpperCase()}</Avatar>}
title={item.Name}
description={`${item.PeersCount} peers`}
avatar={<Avatar>{item.name.slice(0,1).toUpperCase()}</Avatar>}
title={item.name}
description={`${item.peers_count} peers`}
/>
</List.Item>
)}
Expand Down
153 changes: 121 additions & 32 deletions src/components/AccessControlNew.tsx

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {useAuth0} from "@auth0/auth0-react";
import {useLocation} from 'react-router-dom';
import {Menu, Row, Col, Grid, Dropdown, Avatar, Button, Typography, Space} from 'antd'
import {ItemType} from "antd/lib/menu/hooks/useItems";
import {UserOutlined} from "@ant-design/icons";
import {AvatarSize} from "antd/es/avatar/SizeContext";
import { UserOutlined } from '@ant-design/icons';

const { Text } = Typography
const { useBreakpoint } = Grid;
Expand All @@ -30,8 +30,8 @@ const Navbar = () => {
{ label: (<Link to="/peers">Peers</Link>), key: '/peers' },
{ label: (<Link to="/add-peer">Add Peer</Link>), key: '/add-peer' },
{ label: (<Link to="/setup-keys">Setup Keys</Link>), key: '/setup-keys' },
/*{ label: (<Link to="/acls">Access Control</Link>), key: '/acls' },
{ label: (<Link to="/activity">Activity</Link>), key: '/activity' },*/
{ label: (<Link to="/acls">Access Control</Link>), key: '/acls' },
// { label: (<Link to="/activity">Activity</Link>), key: '/activity' },
{ label: (<Link to="/users">Users</Link>), key: '/users' }
] as ItemType[])

Expand Down Expand Up @@ -80,7 +80,7 @@ const Navbar = () => {

const createAvatar = (size:AvatarSize) => {
return user?.picture ? (
<Avatar size={size} src={user?.picture}/>
<Avatar size={size} src={user?.picture} icon={<UserOutlined />} />
) : (
<Avatar size={size}>{(user?.name || '').slice(0, 1).toUpperCase()}</Avatar>
)
Expand Down
193 changes: 193 additions & 0 deletions src/components/PeerGroupsUpdate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import React, {useEffect, useRef, useState} from 'react';
import {useDispatch, useSelector} from "react-redux";
mlsmaycon marked this conversation as resolved.
Show resolved Hide resolved
import {RootState} from "typesafe-actions";
import { actions as peerActions } from '../store/peer';
import {
Col,
Row,
Typography,
Space,
Button, Drawer, Form, Select, Tag, Divider
} from "antd";
import type { CustomTagProps } from 'rc-select/lib/BaseSelect'
import {useAuth0} from "@auth0/auth0-react";
import {PeerGroupsToSave} from "../store/peer/types";
import {Group, GroupPeer} from "../store/group/types";

const { Paragraph } = Typography;
const { Option } = Select;

const PeerGroupsUpdate = () => {
const { getAccessTokenSilently } = useAuth0()
const dispatch = useDispatch()
const groups = useSelector((state: RootState) => state.group.data)
const peer = useSelector((state: RootState) => state.peer.peer)
const updateGroupsVisible = useSelector((state: RootState) => state.peer.updateGroupsVisible)
const savedGroups = useSelector((state: RootState) => state.peer.savedGroups)

const [tagGroups, setTagGroups] = useState([] as string[])
const [selectedTagGroups, setSelectedTagGroups] = useState([] as string[])
const [peerGroups, setPeerGroups] = useState([] as GroupPeer[])
const [peerGroupsToSave, setPeerGroupsToSave] = useState({
ID: '',
groupsNoId: [],
groupsToSave: [],
groupsToRemove: [],
mlsmaycon marked this conversation as resolved.
Show resolved Hide resolved
groupsToAdd: []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Replace ····groupsToAdd:·[] with groupsToAdd:·[],

Suggested change
groupsToAdd: []
groupsToAdd: [],

} as PeerGroupsToSave)

const [form] = Form.useForm()

useEffect(() => {
if (!peer) return
const gs = peer?.groups?.map(g => ({id: g?.id || '', name: g.name} as GroupPeer)) as GroupPeer[]
const gs_name = gs?.map(g => g.name) as string[]
setPeerGroups(gs)
setSelectedTagGroups(gs_name)
form.setFieldsValue({
groups: gs_name
})
}, [peer])

useEffect(() => {
setTagGroups(groups?.map(g => g.name) || [])
}, [groups])

useEffect(() => {
const groupsToRemove = peerGroups.filter(pg => !selectedTagGroups.includes(pg.name)).map(g => g.id)
const groupsToAdd = (groups as Group[]).filter(g => selectedTagGroups.includes(g.name) && !groupsToRemove.includes(g.id || '') && !peerGroups.find(pg => pg.id === g.id)).map(g => g.id) as string[]
const groupsNoId = selectedTagGroups.filter(stg => !groups.find(g => g.name === stg))
setPeerGroupsToSave({
...peerGroupsToSave,
ID: peer?.id || '',
groupsToRemove,
groupsToAdd,
groupsNoId
})
}, [selectedTagGroups])
mlsmaycon marked this conversation as resolved.
Show resolved Hide resolved

const tagRender = (props: CustomTagProps) => {
const { label, value, closable, onClose } = props;
const onPreventMouseDown = (event: React.MouseEvent<HTMLSpanElement>) => {
event.preventDefault();
event.stopPropagation();
};

return (
<Tag
color="blue"
onMouseDown={onPreventMouseDown}
closable={closable}
onClose={onClose}
style={{ marginRight: 3 }}
>
<strong>{value}</strong>
</Tag>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Replace ············ with ······

Suggested change
</Tag>
</Tag>

);
}
mlsmaycon marked this conversation as resolved.
Show resolved Hide resolved

const optionRender = (label: string) => {
let peersCount = ''
const g = groups.find(_g => _g.name === label)
if (g) peersCount = ` - ${g.peers_count || 0} ${(!g.peers_count || parseInt(g.peers_count) !== 1) ? 'peers' : 'peer'} `
return (
<>
<Tag
color="blue"
style={{ marginRight: 3 }}
>
<strong>{label}</strong>
</Tag>
<span style={{fontSize: ".85em"}}>{peersCount}</span>
</>
)
}

const dropDownRender = (menu: React.ReactElement) => (
<>
{menu}
<Divider style={{ margin: '8px 0' }} />
<Row style={{padding: '0 8px 4px'}}>
<Col flex="auto">
<span style={{color: "#9CA3AF"}}>Add new group by pressing "Enter"</span>
</Col>
<Col flex="none">
<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.70455 7.19176V5.89915H10.3949C10.7727 5.89915 11.1174 5.80634 11.429 5.62074C11.7405 5.43513 11.9875 5.18655 12.1697 4.875C12.3554 4.56345 12.4482 4.21875 12.4482 3.84091C12.4482 3.46307 12.3554 3.12003 12.1697 2.81179C11.9841 2.50024 11.7356 2.25166 11.424 2.06605C11.1158 1.88044 10.7727 1.78764 10.3949 1.78764H9.83807V0.5H10.3949C11.0114 0.5 11.5715 0.650805 12.0753 0.952414C12.5791 1.25402 12.9818 1.65672 13.2834 2.16051C13.585 2.6643 13.7358 3.22443 13.7358 3.84091C13.7358 4.30161 13.648 4.73414 13.4723 5.13849C13.3 5.54285 13.0613 5.89915 12.7564 6.20739C12.4515 6.51562 12.0968 6.75758 11.6925 6.93324C11.2881 7.10559 10.8556 7.19176 10.3949 7.19176H1.70455ZM4.90128 11.0646L0.382102 6.54545L4.90128 2.02628L5.79119 2.91619L2.15696 6.54545L5.79119 10.1747L4.90128 11.0646Z" fill="#9CA3AF"/>
</svg>
</Col>
</Row>
</>
)

const setUpdateGroupsVisible = (status:boolean) => {
dispatch(peerActions.setUpdateGroupsVisible(status));
}

const onCancel = () => {
dispatch(peerActions.setPeer(null))
setUpdateGroupsVisible(false)
}

const onChange = (data:any) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Replace ····const·onChange·=·(data: with ··const·onChange·=·(data:·

Suggested change
const onChange = (data:any) => {
const onChange = (data: any) => {

//setFormRule({...formRule, ...data})
}

const handleChangeTags = (value: string[]) => {
setSelectedTagGroups(value)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Replace ········setSelectedTagGroups(value) with ····setSelectedTagGroups(value);

Suggested change
setSelectedTagGroups(value)
setSelectedTagGroups(value);

};

const handleFormSubmit = () => {
form.validateFields()
.then((values) => {
dispatch(peerActions.saveGroups.request({getAccessTokenSilently, payload: peerGroupsToSave}))
mlsmaycon marked this conversation as resolved.
Show resolved Hide resolved
})
.catch((errorInfo) => {
console.log('errorInfo', errorInfo)
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Replace ············ with ······

Suggested change
});
});

}

return (
<>
{peer &&
<Drawer
title={`${peer.name}`}
forceRender={true}
visible={true}
bodyStyle={{paddingBottom: 80}}
onClose={onCancel}
autoFocus={true}
footer={
mlsmaycon marked this conversation as resolved.
Show resolved Hide resolved
<Space style={{display: 'flex', justifyContent: 'end'}}>
<Button onClick={onCancel} disabled={savedGroups.loading}>Cancel</Button>
<Button type="primary" disabled={savedGroups.loading || (!peerGroupsToSave.groupsToRemove.length && !peerGroupsToSave.groupsToAdd.length && !peerGroupsToSave.groupsNoId.length)} onClick={handleFormSubmit}>Save</Button>
</Space>
}
>
<Form layout="vertical" hideRequiredMark form={form} onValuesChange={onChange}>
<Row gutter={16}>
<Col span={24}>
<Form.Item
name="groups"
label="Groups"
rules={[{required: true, message: 'Please enter ate least one group'}]}
style={{display: 'flex'}}
>
<Select mode="tags" style={{ width: '100%' }} placeholder="Select groups..." tagRender={tagRender} dropdownRender={dropDownRender} onChange={handleChangeTags}>
{
tagGroups.map(m =>
<Option key={m}>{optionRender(m)}</Option>
)
}
</Select>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Delete ··················

Suggested change
</Select>
</Select>

</Form.Item>
</Col>
</Row>
</Form>
</Drawer>
}
</>
)
}

export default PeerGroupsUpdate
4 changes: 2 additions & 2 deletions src/components/SetupKeyNew.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ const SetupKeyNew = () => {
const onCancel = () => {
if (createdSetupKey.loading) return
dispatch(setupKeyActions.setSetupKey({
Name: '',
Type: 'reusable'
name: '',
type: 'reusable'
} as SetupKey))
setVisibleNewSetupKey(false)
}
Expand Down
12 changes: 12 additions & 0 deletions src/components/Spin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import {SpinProps} from "antd";

const TableSpin = (loading: boolean): SpinProps => {
return {
spinning: loading,
delay: 1,
size: "large"
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codacy has a fix for the issue: Replace ····} with ··};

Suggested change
}
};

}

export default TableSpin;
12 changes: 11 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,17 @@ body {
color: rgba(0, 0, 0, .85) !important;
}

.access-control.ant-drawer-title:hover {
.access-control-table .tooltip-label:hover {
text-decoration: underline;
cursor: pointer;
}

.access-control.input-text:hover {
text-decoration: underline;
cursor: pointer;
}

.access-control.ant-drawer-subtitle {
line-height: 22px;
margin: 24px 0;
}
13 changes: 0 additions & 13 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,6 @@ const providerConfig = {
onRedirectCallback,
};

/*
ReactDOM.render(
<Auth0Provider {...providerConfig}>
<React.StrictMode>
<BrowserRouter>
<App/>
</BrowserRouter>
</React.StrictMode>
</Auth0Provider>,
document.getElementById('root')
);
*/

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
Expand Down
4 changes: 2 additions & 2 deletions src/store/group/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function* saveGroup(action: ReturnType<typeof actions.saveGroup.request>)
} as CreateResponse<Group | null>))

let effect
if (action.payload.payload.ID) {
if (action.payload.payload.id) {
effect = yield call(service.editGroup, action.payload);
} else {
effect = yield call(service.createGroup, action.payload);
Expand Down Expand Up @@ -94,7 +94,7 @@ export function* deleteGroup(action: ReturnType<typeof actions.deleteGroup.reque
} as DeleteResponse<string | null>));

const rules = (yield select(state => state.rule.data)) as Group[]
yield put(actions.getGroups.success(rules.filter((p:Group) => p.ID !== action.payload.payload)))
yield put(actions.getGroups.success(rules.filter((p:Group) => p.id !== action.payload.payload)))
} catch (err) {
yield put(actions.deleteGroup.failure({
loading: false,
Expand Down
4 changes: 3 additions & 1 deletion src/store/group/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ export default {
);
},
async editGroup(payload:RequestPayload<Group>): Promise<ApiResponse<Group>> {
const id = payload.payload.id
delete payload.payload.id
return apiClient.put<Group>(
`${baseUrl}`,
`${baseUrl}/${id}`,
payload
);
},
Expand Down
13 changes: 9 additions & 4 deletions src/store/group/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export interface Group {
ID?: string;
Name: string;
Peers?: any[];
PeersCount?: string;
id?: string;
name: string;
peers?: GroupPeer[] | string[];
peers_count?: string;
}

export interface GroupPeer {
id: string,
name: string
}
Loading