github.com/argoproj/argo-cd@v1.8.7/ui/src/app/settings/components/project-role-policies-edit/project-role-policies-edit.tsx (about) 1 import * as React from 'react'; 2 import * as ReactForm from 'react-form'; 3 4 import {DataLoader} from '../../../shared/components'; 5 import {Application} from '../../../shared/models'; 6 import {services} from '../../../shared/services'; 7 8 interface ProjectRolePoliciesProps { 9 projName: string; 10 roleName: string; 11 policies: string[]; 12 formApi: ReactForm.FormApi; 13 newRole: boolean; 14 } 15 16 function generatePolicy(project: string, role: string, action?: string, object?: string, permission?: string): string { 17 return `p, proj:${project}:${role}, applications, ${action || ''}, ${object ? project + '/' + object : ''}, ${permission || ''}`; 18 } 19 20 const actions = ['get', 'create', 'update', 'delete', 'sync', 'override']; 21 22 export const ProjectRolePoliciesEdit = (props: ProjectRolePoliciesProps) => ( 23 <DataLoader load={() => services.applications.list([props.projName], {fields: ['items.metadata.name']}).then(list => list.items)}> 24 {applications => ( 25 <React.Fragment> 26 <h4>Policy Rules</h4> 27 <div>Manage this role's permissions to applications</div> 28 <div className='argo-table-list'> 29 <div className='argo-table-list__head'> 30 <div className='row'> 31 <div className='columns small-4'>ACTION</div> 32 <div className='columns small-4'>APPLICATION</div> 33 <div className='columns small-4'>PERMISSION</div> 34 </div> 35 </div> 36 <div className='argo-table-list__row'> 37 {props.policies.map((policy, i) => ( 38 <Policy 39 key={i} 40 field={['policies', i]} 41 formApi={props.formApi} 42 policy={policy} 43 projName={props.projName} 44 roleName={props.roleName} 45 deletePolicy={() => props.formApi.setValue('policies', removeEl(props.policies, i))} 46 availableApps={applications} 47 actions={actions} 48 /> 49 ))} 50 <div className='row'> 51 <div className='columns small-4'> 52 <a 53 onClick={() => { 54 const newPolicy = generatePolicy(props.projName, props.roleName); 55 props.formApi.setValue('policies', (props.formApi.values.policies || []).concat(newPolicy)); 56 }}> 57 Add policy 58 </a> 59 </div> 60 </div> 61 </div> 62 </div> 63 </React.Fragment> 64 )} 65 </DataLoader> 66 ); 67 68 interface PolicyProps { 69 projName: string; 70 roleName: string; 71 policy: string; 72 fieldApi: ReactForm.FieldApi; 73 actions: string[]; 74 availableApps: Application[]; 75 deletePolicy: () => void; 76 } 77 78 function removeEl(items: any[], index: number) { 79 items.splice(index, 1); 80 return items; 81 } 82 83 class PolicyWrapper extends React.Component<PolicyProps, any> { 84 public render() { 85 return ( 86 <div className='row'> 87 <div className='columns small-4'> 88 <datalist id='action'> 89 {this.props.actions !== undefined && this.props.actions.length > 0 && this.props.actions.map(action => <option key={action}>{action}</option>)} 90 <option key='wildcard'>*</option> 91 </datalist> 92 <input 93 className='argo-field' 94 list='action' 95 value={this.getAction()} 96 onChange={(e: React.ChangeEvent<HTMLInputElement>) => { 97 this.setAction(e.target.value); 98 }} 99 /> 100 </div> 101 <div className='columns small-4'> 102 <datalist id='object'> 103 {this.props.availableApps !== undefined && 104 this.props.availableApps.length > 0 && 105 this.props.availableApps.map(app => ( 106 <option key={app.metadata.name}> 107 {this.props.projName}/{app.metadata.name} 108 </option> 109 ))} 110 <option key='wildcard'>{`${this.props.projName}/*`}</option> 111 </datalist> 112 <input 113 className='argo-field' 114 list='object' 115 value={this.getObject()} 116 onChange={(e: React.ChangeEvent<HTMLInputElement>) => { 117 this.setObject(e.target.value); 118 }} 119 /> 120 </div> 121 <div className='columns small-3'> 122 <datalist id='permission'> 123 <option>allow</option> 124 <option>deny</option> 125 </datalist> 126 <input 127 className='argo-field' 128 list='permission' 129 value={this.getPermission()} 130 onChange={(e: React.ChangeEvent<HTMLInputElement>) => { 131 this.setPermission(e.target.value); 132 }} 133 /> 134 </div> 135 <div className='columns small-1'> 136 <i className='fa fa-times' onClick={() => this.props.deletePolicy()} style={{cursor: 'pointer'}} /> 137 </div> 138 </div> 139 ); 140 } 141 142 private getAction(): string { 143 const fields = (this.props.fieldApi.getValue() as string).split(','); 144 if (fields.length !== 6) { 145 return ''; 146 } 147 return fields[3].trim(); 148 } 149 150 private setAction(action: string) { 151 const fields = (this.props.fieldApi.getValue() as string).split(','); 152 if (fields.length !== 6) { 153 this.props.fieldApi.setValue(generatePolicy(this.props.projName, this.props.roleName, action, '', '')); 154 return; 155 } 156 fields[3] = ` ${action}`; 157 this.props.fieldApi.setValue(fields.join()); 158 } 159 160 private getObject(): string { 161 const fields = (this.props.fieldApi.getValue() as string).split(','); 162 if (fields.length !== 6) { 163 return ''; 164 } 165 return fields[4].trim(); 166 } 167 168 private setObject(object: string) { 169 const fields = (this.props.fieldApi.getValue() as string).split(','); 170 if (fields.length !== 6) { 171 this.props.fieldApi.setValue(generatePolicy(this.props.projName, this.props.roleName, '', object, '')); 172 return; 173 } 174 fields[4] = ` ${object}`; 175 this.props.fieldApi.setValue(fields.join()); 176 } 177 178 private getPermission(): string { 179 const fields = (this.props.fieldApi.getValue() as string).split(','); 180 if (fields.length !== 6) { 181 return ''; 182 } 183 return fields[5].trim(); 184 } 185 private setPermission(permission: string) { 186 const fields = (this.props.fieldApi.getValue() as string).split(','); 187 if (fields.length !== 6) { 188 this.props.fieldApi.setValue(generatePolicy(this.props.projName, this.props.roleName, '', '', permission)); 189 return; 190 } 191 fields[5] = ` ${permission}`; 192 this.props.fieldApi.setValue(fields.join()); 193 } 194 } 195 196 const Policy = ReactForm.FormField(PolicyWrapper);