diff --git a/src/app/core/components/user-services/user-services.component.html b/src/app/core/components/user-services/user-services.component.html
index c160b33875b4f7689b9ef24a69cffdcd0f88ffd4..cf125925f5c6ea1a9eedab1f3aeb4186dba79b76 100644
--- a/src/app/core/components/user-services/user-services.component.html
+++ b/src/app/core/components/user-services/user-services.component.html
@@ -25,4 +25,49 @@
       </tr>
     </tbody>
   </table>
+
+  <div>
+    <div class="requestable-services-table-wrapper">
+      <table class="table">
+        <thead>
+          <tr>
+            <th></th>
+            <th i18n="@@userService.name">Name</th>
+            <th>Service</th>
+            <th i18n="@@userService.add">Add</th>
+          </tr>
+        </thead>
+        <tbody>
+          <ng-container *ngFor="let service of requestableServices; let index = index">
+            <tr>
+              <td (click)="toogleRow(index)">
+                <i class="fas fa-angle-right" *ngIf="!isRowOpened(index); else angleDownTemplate"></i>
+                <ng-template #angleDownTemplate>
+                  <i class="fas fa-angle-down"></i>
+                </ng-template>
+              </td>
+              <td>{{ service.name }}</td>
+              <td>all</td>
+              <td><input type="checkbox" (click)="toogleService(service.id)" [checked]="allModeAreSelected(service.id)"></td>
+            </tr>
+            <ng-container *ngIf="isRowOpened(index)">
+              <tr *ngFor="let mode of service.modes;">
+                <td></td>
+                <td></td>
+                <td>
+                  {{ mode.name }}
+                </td>
+                <td>
+                  <input type="checkbox" [(ngModel)]="mode.selected">
+                </td>
+              </tr>
+            </ng-container>
+          </ng-container>
+        </tbody>
+      </table>
+    </div>
+  </div>
+  <button type="button" class="button button-gl" [disabled]="requestedServices.length <= 0" (click)="requestAccess()" i18n="@@userService.sendRequest">
+    Send my request
+  </button>
 </section>
\ No newline at end of file
diff --git a/src/app/core/components/user-services/user-services.component.scss b/src/app/core/components/user-services/user-services.component.scss
index fc3be280571f09b972f353297f005f08775e72b4..6d9bd22910bef69ca2a47871f78d55282245cdca 100644
--- a/src/app/core/components/user-services/user-services.component.scss
+++ b/src/app/core/components/user-services/user-services.component.scss
@@ -1,3 +1,13 @@
 .lock-open-icon {
   margin-right: 0.5rem;
+}
+
+i {
+  cursor: pointer;
+}
+
+.requestable-services-table-wrapper {
+  max-height: 50vh;
+  overflow-y: scroll;
+  display: inline-block;
 }
\ No newline at end of file
diff --git a/src/app/core/components/user-services/user-services.component.ts b/src/app/core/components/user-services/user-services.component.ts
index 264cc09d7863183350da8151e425fc8b6140d0c9..7a8941b47c37827ad9e9a33be35aa8365bdd872a 100644
--- a/src/app/core/components/user-services/user-services.component.ts
+++ b/src/app/core/components/user-services/user-services.component.ts
@@ -1,7 +1,10 @@
 import { Component, OnInit } from '@angular/core';
-import { AuthService } from '../../services';
-import { UserService } from '../../models/auth.model';
+import { AuthService, NotificationService } from '../../services';
 import { statuses } from '../../../../i18n/user-services/user-services';
+import { IRequestedAccessService, IRestrictedAccessService, IMode } from '../../models/auth.model';
+import { forkJoin } from 'rxjs';
+import { Notification } from '../../models';
+import { messages } from '../../../../i18n/notification-messages/notification-messages';
 
 @Component({
   selector: 'app-user-services',
@@ -10,20 +13,148 @@ import { statuses } from '../../../../i18n/user-services/user-services';
 })
 export class UserServicesComponent implements OnInit {
 
-  userServices: UserService[] = [];
+  userServices: IRequestedAccessService[] = [];
+  restrictedAccessServices: IRestrictedAccessService[] = [];
+  modes: IMode[] = [];
   statusesTrad = statuses;
 
+  openedRow: number[] = [];
+
+  requestableServices = [];
+
   constructor(
     private _authService: AuthService,
+    private _notificationService: NotificationService,
   ) { }
 
   ngOnInit() {
-    this.getUserServices();
+    forkJoin([
+      this._authService.getUserServices(),
+      this._authService.getModes(),
+      this._authService.getRestrictedAccessService(),
+    ]).subscribe(
+      (results) => {
+        this.userServices = results[0];
+        this.modes = results[1];
+        this.restrictedAccessServices = results[2];
+
+        this.initRequestableServices();
+      },
+      (err) => {
+        console.log('Something went wrong', err);
+      },
+    );
+  }
+
+  initRequestableServices() {
+    this.requestableServices = [];
+    // Iterate over the access restricted services
+    this.restrictedAccessServices.forEach((service) => {
+      const temp = { id: service.dataset_id, name: service.dataset_name, modes: [] };
+
+      this.modes.forEach((mode) => {
+        // Add mode if not already in the user available dataset
+        // meaning if the user didn't already have requested the access for that dataset and that mode)
+        if (
+          this.userServices.findIndex(
+            us => us.dataset_id === service.dataset_id && us.ressource === mode.name,
+          ) === -1) {
+          temp.modes.push({ id: mode.id, name: mode.name, selected: false });
+        }
+      });
+
+      this.requestableServices.push(temp);
+    });
+  }
+
+  // Returns 1 if number is in array, -1 else
+  isRowOpened(id: number): boolean {
+    return this.openedRow.includes(id);
+  }
+
+  toogleRow(id: number) {
+    if (this.isRowOpened(id)) {
+      this.removeRow(id);
+    } else {
+      this.addRow(id);
+    }
+  }
+
+  addRow(id: number) {
+    this.openedRow.push(id);
+  }
+
+  removeRow(id) {
+    const index = this.openedRow.findIndex(row => row === id);
+    if (index !== -1) {
+      this.openedRow.splice(index, 1);
+    }
+  }
+
+  toogleService(serviceId) {
+    const service = this.requestableServices.find(e => e.id === serviceId);
+    if (service) {
+      let bool = false;
+      const unselectedMode = service.modes.find(e => e.selected === false);
+
+      if (unselectedMode) {
+        bool = true;
+      }
+
+      service.modes.forEach((mode) => {
+        mode.selected = bool;
+      });
+    }
+  }
+
+  allModeAreSelected(serviceId: number) {
+    let res = true;
+
+    const service = this.requestableServices.find(e => e.id === serviceId);
+    if (service) {
+      const unselectedMode = service.modes.find(e => e.selected === false);
+
+      if (unselectedMode) {
+        res = false;
+      }
+    }
+
+    return res;
+  }
+
+  get requestedServices() {
+    return this.requestableServices.filter((e) => {
+      return e.modes.findIndex(m => m.selected === true) !== -1 ? true : false;
+    }).map((e) => {
+      const modesIdArray = e.modes.filter(m => m.selected === true).map((m) => { return { id: m.id, name: m.name }; });
+      return { id: e.id, name: e.name, modes: modesIdArray };
+    });
   }
 
-  getUserServices() {
-    this._authService.getUserServices().subscribe((userServices) => {
-      this.userServices = userServices;
+  requestAccess() {
+    this.requestedServices.forEach((e) => {
+      this._authService.requestAccessToService({ id: e.id, modes: e.modes.map(e => e.id) }).subscribe(
+        (res) => {
+          this._notificationService.notify(new Notification({
+            type: 'success',
+            message: `${messages.userServices.addSuccess} ${e.name} (${e.modes.map(e => e.name)})`,
+          }));
+          this._authService.getUserServices().subscribe(
+            (res) => {
+              this.userServices = res;
+              this.initRequestableServices();
+            },
+            (err) => {
+            },
+          );
+        },
+        (err) => {
+          console.log(err);
+          this._notificationService.notify(new Notification({
+            type: 'error',
+            message: `${messages.userServices.addFailed} "${e.name}" (${e.modes.map(e => e.name)})`,
+          }));
+        });
     });
   }
 
diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts
index 488fe2111c2d8e7bd8ec8e4d5b7696b434361e7c..79f3eefe1d08207fc9b0fb62f68fcb68a38d7e14 100644
--- a/src/app/core/core.module.ts
+++ b/src/app/core/core.module.ts
@@ -8,7 +8,7 @@ import { ErrorsHandler } from './handlers/errors-handler';
 import { HttpErrorResponseInterceptor } from './interceptors/http-error-response-interceptor';
 import { HTTP_INTERCEPTORS } from '@angular/common/http';
 import { CoreServices } from './services';
-import { ReactiveFormsModule } from '@angular/forms';
+import { ReactiveFormsModule, FormsModule } from '@angular/forms';
 import { AuthInterceptor } from './interceptors/auth-interceptor';
 import { GeosourceModule } from '../geosource/geosource.module';
 import { CoreGuards } from './guards';
@@ -19,6 +19,7 @@ import { CoreGuards } from './guards';
     CoreRoutingModule,
     SharedModule,
     ReactiveFormsModule,
+    FormsModule,
     GeosourceModule.forRoot(),
   ],
   declarations: [CoreComponents],
diff --git a/src/app/core/models/auth.model.ts b/src/app/core/models/auth.model.ts
index ec157b6caf1b292692a3d2889c31e2023351ca95..c3b13bf4441fc4fc7764d5c074442d80687e7f4b 100644
--- a/src/app/core/models/auth.model.ts
+++ b/src/app/core/models/auth.model.ts
@@ -66,7 +66,7 @@ export class LegacyAccount {
   }
 }
 
-export interface UserService {
+export interface IRequestedAccessService {
   dataset_id: number;
   dataset_name: string;
   status: string;
@@ -74,3 +74,16 @@ export interface UserService {
   url_pattern: string;
   valid_until: Date;
 }
+
+export interface IRestrictedAccessService {
+  dataset_id: number;
+  dataset_name: string;
+  abstract: string;
+  service_url: string;
+}
+
+export interface IMode {
+  id: number;
+  name: string;
+  abstract: string;
+}
diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts
index facc8e86ea2803aa195b6ea83ab1c0407ed0d253..4b77e878da9ed4d6fd83ab993d18c709104062ef 100644
--- a/src/app/core/services/auth.service.ts
+++ b/src/app/core/services/auth.service.ts
@@ -6,7 +6,7 @@ import { map } from 'rxjs/operators';
 import { Observable } from 'rxjs';
 import { ILoginResponse, User, LegacyAccount } from '../models';
 import { environment } from '../../../environments/environment';
-import { UserService } from '../models/auth.model';
+import { IRequestedAccessService, IRestrictedAccessService, IMode } from '../models/auth.model';
 
 @Injectable()
 export class AuthService {
@@ -78,8 +78,47 @@ export class AuthService {
     return this._user != null;
   }
 
-  getUserServices(): Observable<UserService[]> {
-    return this._http.get<UserService[]>(`${environment.middlewareLegacyAuth}get_user_service/`).pipe(
+  getUserServices(): Observable<IRequestedAccessService[]> {
+    return this._http.get<IRequestedAccessService[]>(`${environment.middlewareLegacyAuth}get_user_service/`).pipe(
+      map(
+        (res) => {
+          return res;
+        },
+        (err) => {
+          throw err;
+        },
+      ),
+    );
+  }
+
+  getRestrictedAccessService(): Observable<IRestrictedAccessService[]> {
+    return this._http.get<IRestrictedAccessService[]>(`${environment.middlewareLegacyAuth}get_services`).pipe(
+      map(
+        (res) => {
+          return res;
+        },
+        (err) => {
+          throw err;
+        },
+      ),
+    );
+  }
+
+  getModes(): Observable<IMode[]> {
+    return this._http.get<IMode[]>(`${environment.middlewareLegacyAuth}get_modes`).pipe(
+      map(
+        (res) => {
+          return res;
+        },
+        (err) => {
+          throw err;
+        },
+      ),
+    );
+  }
+
+  requestAccessToService(service) {
+    return this._http.post<any>(`${environment.middlewareLegacyAuth}add_user_service`, service).pipe(
       map(
         (res) => {
           return res;
diff --git a/src/i18n/notification-messages/notification-messages.fr.ts b/src/i18n/notification-messages/notification-messages.fr.ts
index 0d8c3498e8be8ff5300880107b55a0ebd52707ff..bbef064f2f0d269a77c5b3583d0bc300d0618838 100644
--- a/src/i18n/notification-messages/notification-messages.fr.ts
+++ b/src/i18n/notification-messages/notification-messages.fr.ts
@@ -31,4 +31,8 @@ export const messages = {
     existingAccount: 'Un compte existe déjà pour cet email.',
     uncompleteForm: 'Le formulaire est incomplet.',
   },
+  userServices: {
+    addSuccess: 'Vous avez demandé l\'accès à',
+    addFailed: 'Une erreur est survenu lors de la demande d\'accès à ',
+  },
 };
diff --git a/src/i18n/notification-messages/notification-messages.ts b/src/i18n/notification-messages/notification-messages.ts
index 5320aab7b48943b8ec8394503ea3344db8ac6bce..ed8ba1e902ffecd5451e2b4f409f6d7511660709 100644
--- a/src/i18n/notification-messages/notification-messages.ts
+++ b/src/i18n/notification-messages/notification-messages.ts
@@ -30,4 +30,8 @@ export const messages = {
     existingAccount: 'An account already exists for that email.',
     uncompleteForm: 'Incomplete form.',
   },
+  userServices: {
+    addSuccess: 'You requested access to ',
+    addFailed: 'An error occured while requesting access to ',
+  },
 };