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);