Skip to content

Commit

Permalink
Refacto User & Organization (#405)
Browse files Browse the repository at this point in the history
* Prepare Behat scenarios for User system refacto (#339)

* Refacto User login

* Add reset password

* Add Organization promote/revoke User

* Add ROLE_SUPER_ADMIN

* Add User impersonification for super-admin only

* Remove useless ROLE_VOLUNTEER

* wip

* Fix PHP-CS

Co-authored-by: Michel Roca <[email protected]>
  • Loading branch information
vincentchalamon and mRoca committed Nov 13, 2020
1 parent 5d8632d commit 64051aa
Show file tree
Hide file tree
Showing 144 changed files with 1,782 additions and 1,348 deletions.
6 changes: 5 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ COMPOSE_PROJECT_NAME=resop

IMAGE_BUILD_TAG=dev

APP_NB_USERS=10
APP_NB_USERS=15
APP_NB_AVAILABILITIES=3
APP_SLOT_INTERVAL="+2 hours"

Expand All @@ -35,3 +35,7 @@ APP_SECRET=782bb8b0aeb47de4ea870794e79d82cd
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
DATABASE_URL=postgresql://resop:postgrespwd@postgres/resop?serverVersion=11&charset=utf8
###< doctrine/doctrine-bundle ###

###> symfony/mailer ###
MAILER_DSN=smtp://mailcatcher:25
###< symfony/mailer ###
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ SYMFONY_DEPRECATIONS_HELPER=disabled
DATABASE_URL=postgresql://resop:postgrespwd@postgres/resop-test?serverVersion=11&charset=utf8
PANTHER_CHROME_ARGUMENTS="--headless --no-sandbox"
PANTHER_APP_ENV=panther
APP_SLOT_INTERVAL="+2 hours"
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ env:
APP_DEBUG: 0
DATABASE_SERVER_VERSION: 11 # update service "postgresql" if this value change
PANTHER_CHROME_DRIVER_BINARY: /usr/bin/chromedriver
MAILER_DSN: smtp://localhost:25

jobs:
php:
Expand All @@ -32,6 +33,11 @@ jobs:
- 5432:5432
# needed because the postgres container does not provide a healthcheck
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
mailcatcher:
image: tophfr/mailcatcher:0.6.5
ports:
- 1080:80
- 25:25

steps:
- name: set DATABASE_URL environment variable
Expand Down Expand Up @@ -133,6 +139,7 @@ jobs:
- name: Run Behat tests
run: |
bin/post-install-test.sh
sed -i 's#http://mailcatcher#http://localhost:1080#' behat.yml.dist
vendor/bin/behat --format=progress --out=std --format=junit --out=var/behat --tags '~@javascript'
if: always()

Expand Down
4 changes: 2 additions & 2 deletions assets/js/_planning-missions.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ function setSlotMisssion(mission, $slot) {
missionsText += ' ';

// User part
let url = Routing.generate('app_user_availability_mission_modal', { id: mission.id });
let url = Routing.generate('app_user_availability_mission_modal', { mission: mission.id });

if (window.location.pathname.indexOf('organizations') >= 0 && !!mission?.organization?.id) {
// Organization part
url = Routing.generate('app_organization_mission_modal', { organization: mission.organization.id, id: mission.id });
url = Routing.generate('app_organization_mission_modal', { organization: mission.organization.id, mission: mission.id });
}

missionsText += $(`<button type="button" class="btn btn-link" data-toggle="ajax-modal" data-href="${url}">`).text(mission.name)[0].outerHTML;
Expand Down
2 changes: 1 addition & 1 deletion assets/js/fos_js_routes.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"base_url":"","routes":{"app_user_availability_mission_modal":{"tokens":[["text","\/modal"],["variable","\/","\\d+","id",true],["text","\/user\/availability\/missions"]],"defaults":[],"requirements":{"id":"\\d+"},"hosttokens":[],"methods":["GET"],"schemes":[]},"app_organization_mission_modal":{"tokens":[["text","\/modal"],["variable","\/","\\d+","id",true],["text","\/missions"],["variable","\/","\\d+","organization",true],["text","\/organizations"]],"defaults":[],"requirements":{"id":"\\d+","organization":"\\d+"},"hosttokens":[],"methods":["GET"],"schemes":[]},"app_organization_mission_find_by_filters":{"tokens":[["text","\/missions\/find"],["variable","\/","\\d+","organization",true],["text","\/organizations"]],"defaults":[],"requirements":{"organization":"\\d+"},"hosttokens":[],"methods":["GET"],"schemes":[]}},"prefix":"","host":"localhost","port":"","scheme":"http","locale":[]}
{"base_url":"","routes":{"app_user_availability_mission_modal":{"tokens":[["text","\/modal"],["variable","\/","\\d+","mission",true],["text","\/user\/availability\/missions"]],"defaults":[],"requirements":{"mission":"\\d+"},"hosttokens":[],"methods":["GET"],"schemes":[]},"app_organization_mission_modal":{"tokens":[["text","\/modal"],["variable","\/","\\d+","mission",true],["text","\/missions"],["variable","\/","\\d+","organization",true],["text","\/organizations"]],"defaults":[],"requirements":{"mission":"\\d+","organization":"\\d+"},"hosttokens":[],"methods":["GET"],"schemes":[]},"app_organization_mission_find_by_filters":{"tokens":[["text","\/missions\/find"],["variable","\/","\\d+","organization",true],["text","\/organizations"]],"defaults":[],"requirements":{"organization":"\\d+"},"hosttokens":[],"methods":["GET"],"schemes":[]}},"prefix":"","host":"localhost","port":"","scheme":"http","locale":[]}
9 changes: 7 additions & 2 deletions behat.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ default:
suites:
default:
contexts:
- Alex\MailCatcher\Behat\MailCatcherContext
- App\Tests\Behat\CoverageContext
- App\Tests\Behat\DatabaseContext
- App\Tests\Behat\FixturesContext
- App\Tests\Behat\OrganizationPlanningContext
- App\Tests\Behat\ResetPasswordContext
- App\Tests\Behat\SecurityContext
- App\Tests\Behat\TraversingContext
- App\Tests\Behat\UserPlanningContext
- Behat\MinkExtension\Context\MinkContext
- PantherExtension\Context\PantherContext
- PantherExtension\Context\WaitContext:
- PantherExtension\Context\WaitContext
extensions:
PantherExtension\Extension\PantherExtension: ~
Alex\MailCatcher\Behat\MailCatcherExtension\Extension:
url: http://mailcatcher
purge_before_scenario: true
Behat\MinkExtension:
browser_name: chrome
default_session: symfony
Expand All @@ -28,3 +32,4 @@ default:
kernel:
environment: test
debug: true
PantherExtension\Extension\PantherExtension: ~
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"symfony/form": "5.*",
"symfony/framework-bundle": "5.*",
"symfony/intl": "5.*",
"symfony/mailer": "5.0.*",
"symfony/monolog-bundle": "^3.5",
"symfony/security-bundle": "5.*",
"symfony/serializer-pack": "^1.0",
Expand All @@ -35,10 +36,12 @@
"symfony/validator": "5.*",
"symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "5.*",
"symfonycasts/reset-password-bundle": "^1.1",
"twig/cache-extension": "^1.4",
"twig/intl-extra": "^3.0"
},
"require-dev": {
"alexandresalome/mailcatcher": "dev-master",
"behat/behat": "^3.6",
"dama/doctrine-test-bundle": "^6.3",
"escapestudios/symfony2-coding-standard": "^3.11",
Expand Down
1 change: 1 addition & 0 deletions config/bundles.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
Misd\PhoneNumberBundle\MisdPhoneNumberBundle::class => ['all' => true],
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
FOS\JsRoutingBundle\FOSJsRoutingBundle::class => ['all' => true],
SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle::class => ['all' => true],
];
3 changes: 3 additions & 0 deletions config/packages/mailer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
2 changes: 2 additions & 0 deletions config/packages/reset_password.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
symfonycasts_reset_password:
request_password_repository: App\Repository\ResetPasswordRequestRepository
33 changes: 8 additions & 25 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,23 @@ security:
entity:
class: App\Entity\User

organizations:
entity:
class: App\Entity\Organization

encoders:
Symfony\Component\Security\Core\User\UserInterface:
algorithm: auto

role_hierarchy:
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH]

firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false

organizations:
pattern: ^/organizations
anonymous: true
lazy: true
provider: organizations
guard:
authenticators:
- App\Security\OrganizationLoginFormAuthenticator

logout:
path: app_organization_logout
target: app_organization_index

remember_me:
name: remember_me_organization
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /

main:
anonymous: true
lazy: true
provider: users
switch_user: true
guard:
authenticators:
- App\Security\UserLoginFormAuthenticator
Expand All @@ -56,6 +37,8 @@ security:
path: /

access_control:
- { path: ^/(user\/new|login|organizations\/login)$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/organizations, roles: ROLE_ORGANIZATION }
- { path: ^/user/new$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/reset-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
- { path: ^/organizations/, roles: ROLE_ORGANIZATION }
10 changes: 8 additions & 2 deletions config/services_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ services:
resource: '../tests/Behat/*'

App\Tests\Behat\FixturesContext:
$aliceFixturesLoader: '@hautelook_alice.loader'
arguments:
$aliceFixturesLoader: '@hautelook_alice.loader'

App\Tests\Behat\TraversingContext:
$projectDir: '%kernel.project_dir%'
arguments:
$projectDir: '%kernel.project_dir%'

App\Tests\Behat\UserPlanningContext:
arguments:
$slotInterval: '%app.slot_interval%'
7 changes: 6 additions & 1 deletion docker-compose.override.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,9 @@ services:
volumes:
- postgres-data:/var/lib/postgresql/data:rw
# ports:
# - '5432:5432' # Uncomment if you need to access the DB from your host
# - '5432:5432' # Uncomment if you need to access the DB from your host

# mailcatcher:
# ports:
# - '1080:80' # Uncomment if you need to access the mails interface from your host
# - '1025:25' # Uncomment if you need to send mails from your host
3 changes: 3 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ services:
- NODE_ENV=dev
volumes:
- ./:/srv

mailcatcher:
image: tophfr/mailcatcher:0.6.5
4 changes: 2 additions & 2 deletions docs/technical.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ Then, run `docker-compose up -d postgres`. The DB is now available on the `local
If you want to load huge amount of data, for example to test the performances, run the following command in the fpm container:

```bash
bin/tools sh -c "APP_NB_USERS=15 APP_NB_AVAILABILITIES=6 bin/console doctrine:fixtures:load --purge-with-truncate --no-interaction"
bin/tools sh -c "APP_NB_USERS=20 APP_NB_AVAILABILITIES=6 bin/console doctrine:fixtures:load --purge-with-truncate --no-interaction"
```

- APP_NB_USERS: number of users per organization (default: 10)
- APP_NB_USERS: number of users per organization (default: 15)
- APP_NB_AVAILABILITIES: number of days on which generating availabilities per user (default: 3)


Expand Down
65 changes: 20 additions & 45 deletions features/organization/assets.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Feature:
I must be able to list, edit and delete assets in my organization.

Scenario: As an admin of an organization, I can list the assets from my organization
Given I am authenticated as "admin203@resop.com"
And I am on "/organizations/203"
Given I am authenticated as "admin201@resop.com"
And I am on "/organizations/201"
When I follow "Afficher la liste de mes véhicules"
Then I should be on "/organizations/203/assets"
Then I should be on "/organizations/201/assets/"
And the response status code should be 200
And I should see "75992"
And I should see "75996"
Expand All @@ -32,12 +32,12 @@ Feature:

Scenario: As an admin of an organization, I cannot list the assets from an organization I don't have access to
Given I am authenticated as "[email protected]"
When I go to "/organizations/202/assets"
When I go to "/organizations/202/assets/"
Then the response status code should be 403

Scenario: As an admin of a child organization, I cannot list the assets from the parent organization
Given I am authenticated as "admin203@resop.com"
When I go to "/organizations/201/assets"
Given I am authenticated as "admin204@resop.com"
When I go to "/organizations/202/assets/"
Then the response status code should be 403

Scenario Outline: As an admin of an organization, I can add an asset on my organization or children organizations
Expand All @@ -50,69 +50,44 @@ Feature:
And I press "Continuer"
Then the response status code should be 200
And I should be on "<add_url>"
When I fill in the following:
| commissionable_asset[type] | VL |
| commissionable_asset[name] | new vehicule |
| commissionable_asset[hasMobileRadio] | 1 |
| commissionable_asset[hasFirstAidKit] | 1 |
| commissionable_asset[parkingLocation] | some parking location |
| commissionable_asset[contact] | some contact |
| commissionable_asset[seatingCapacity] | 5 |
| commissionable_asset[licensePlate] | some license plate |
| commissionable_asset[comments] | some comments |
When I fill in "commissionable_asset[name]" with "new vehicule"
And I press "Enregistrer"
Then I should be on "<list_url>"
And the response status code should be 200
And I should see "Véhicule créé"
And I should see "VL - new vehicule"
When I follow the last "Modifier"
Then I should be on "/organizations/203/assets/1/edit"
And the response status code should be 200
And the "commissionable_asset_type" field should contain "VL"
And the "commissionable_asset_name" field should contain "new vehicule"
And the "commissionable_asset_hasMobileRadio_0" checkbox is checked
And the "commissionable_asset_hasFirstAidKit_0" checkbox is checked
And the "commissionable_asset_parkingLocation" field should contain "some parking location"
And the "commissionable_asset_contact" field should contain "some contact"
And the "commissionable_asset_seatingCapacity" field should contain "5"
And the "commissionable_asset_licensePlate" field should contain "some license plate"
And the "commissionable_asset_comments" field should contain "some comments"
And I should see "new vehicule"
Examples:
| login | list_url | preAdd_url | add_url |
# todo: there is a bug when using parent organization: https://github.com/crf-devs/resop/issues/360
# todo: how to create a new asset on a children organization (but not on current one)?
# | [email protected] | /organizations/201/assets?organization=203 | /organizations/201/assets/preAdd | /organizations/201/assets/add |
| admin203@resop.com | /organizations/203/assets | /organizations/203/assets/preAdd | /organizations/203/assets/add |
| login | list_url | preAdd_url | add_url |
| admin201@resop.com | /organizations/201/assets/?organizationId=203 | /organizations/201/assets/preAdd?organizationId=203 | /organizations/201/assets/add?organizationId=203 |
| admin204@resop.com | /organizations/204/assets/ | /organizations/204/assets/preAdd | /organizations/204/assets/add |

@javascript
Scenario: As an admin of an organization, I can display an asset modal
Scenario: As an admin of an admin of an organization, I can display an asset modal
Given I am authenticated as "[email protected]"
When I go to "/organizations/201/assets"
When I go to "/organizations/201/assets/"
And I press "Afficher"
And I wait for ".modal-show-asset-inner" to be visible
Then I should see "Modifier"
And I follow "Modifier"
Then I should be on "/organizations/201/assets/75012/edit?organizationId=203"
Then I should be on "/organizations/201/assets/75992/edit"

Scenario Outline: As an admin of an organization, I can update an asset from my organization or children organizations
Given I am authenticated as "<login>"
When I go to "<edit_url>"
Then I should be on "<edit_url>"
And the response status code should be 200
And the "commissionable_asset_name" field should contain "75012"
When I fill in the following:
| commissionable_asset[name] | new name |
And the "commissionable_asset_name" field should contain "<name>"
When I fill in "commissionable_asset[name]" with "new name"
And I press "Enregistrer"
Then I should be on "<list_url>"
And the response status code should be 200
And I should see "Véhicule \"VPSP - new name\" mis à jour avec succès"
When I go to "<edit_url>"
And the "commissionable_asset_name" field should contain "new name"
Examples:
| login | edit_url | list_url |
# todo: there is a bug when using parent organization: https://github.com/crf-devs/resop/issues/360
# | [email protected] | /organizations/201/assets/75012/edit | /organizations/201/assets?organization=203 |
| admin203@resop.com | /organizations/203/assets/75012/edit | /organizations/203/assets |
| login | name | edit_url | list_url |
| admin201@resop.com | 75012 | /organizations/201/assets/75012/edit | /organizations/201/assets/?organizationId=203 |
| admin204@resop.com | 77102 | /organizations/204/assets/77102/edit | /organizations/204/assets/ |

Scenario: As an admin of a parent organization, I cannot update an asset from an organization I don't have access to
Given I am authenticated as "[email protected]"
Expand Down Expand Up @@ -149,7 +124,7 @@ Feature:

Scenario: As an admin of a parent organization, I cannot delete an asset from another organization
Given I am authenticated as "[email protected]"
When I go to "/organizations/202/assets"
When I go to "/organizations/202/assets/"
Then the response status code should be 403
When I go to "/organizations/202/assets/77992/delete"
Then the response status code should be 403
Expand Down
8 changes: 4 additions & 4 deletions features/organization/forecast.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ Feature:
I must be able to search for available users and assets.

Scenario: As an authenticated children organization, I cannot use the forecast search form
Given I am authenticated as "UL 01-02"
When I go to "/organizations/201/forecast/"
Given I am authenticated as "[email protected]"
When I go to "/organizations/202/forecast/"
Then the response status code should be 403

Scenario: As an authenticated parent organization, I can access the forecast search form
Given I am authenticated as "DT75"
Given I am authenticated as "[email protected]"
When I go to "/organizations/201"
Then I should see "Projections"
When I follow "Projections"
Expand All @@ -20,7 +20,7 @@ Feature:

@javascript
Scenario: As an authenticated parent organization, I can use the forecast search form
Given I am authenticated as "DT75"
Given I am authenticated as "[email protected]"
And I am on "/organizations/201/forecast/"
When I click on "#availableRange"
Then I wait for ".daterangepicker" to be visible
Expand Down
Loading

0 comments on commit 64051aa

Please sign in to comment.