├── .coveralls.yml ├── .gitignore ├── .styleci.yml ├── .travis.yml ├── Controller └── GeneratorController.php ├── DependencyInjection ├── Configuration.php └── HackzillaPasswordGeneratorExtension.php ├── Entity └── Options.php ├── Exception └── UnknownGeneratorException.php ├── Form └── Type │ └── OptionType.php ├── HackzillaPasswordGeneratorBundle.php ├── Makefile ├── README.md ├── Resources ├── config │ ├── routing.yml │ └── services.yml ├── translations │ ├── messages.bg.xlf │ ├── messages.en.xlf │ └── messages.fr.xlf └── views │ ├── Generator │ ├── computer-layout.html.twig │ ├── form.html.twig │ ├── human-layout.html.twig │ └── hybrid-layout.html.twig │ ├── layout.html.twig │ └── menu.html.twig ├── Tests ├── Controller │ └── GeneratorControllerTest.php ├── Entity │ └── OptionsTest.php ├── Form │ └── Type │ │ └── OptionTypeTest.php ├── PublicService.php ├── TestKernel.php └── bootstrap.php ├── composer.json └── phpunit.xml.dist /.coveralls.yml: -------------------------------------------------------------------------------- 1 | # single file 2 | coverage_clover: build/logs/clover.xml 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/* 2 | composer.lock 3 | .php_cs.cache 4 | .phpunit 5 | .phpunit.result.cache 6 | /phpunit.xml 7 | /.idea 8 | 9 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: symfony 2 | 3 | enabled: 4 | - align_double_arrow 5 | - newline_after_open_tag 6 | - ordered_use 7 | - short_array_syntax 8 | - php_unit_construct 9 | - php_unit_strict 10 | 11 | disabled: 12 | - unalign_double_arrow 13 | - unalign_equals 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | 3 | language: php 4 | 5 | php: 6 | - 8.0 7 | - 8.1 8 | - nightly 9 | 10 | env: 11 | global: 12 | - PATH="$HOME/.composer/vendor/bin:$PATH" 13 | 14 | matrix: 15 | fast_finish: true 16 | include: 17 | - php: 8.0 18 | env: CS_FIXER=run 19 | - php: 8.0 20 | env: SYMFONY_VERSION="5.4.*" 21 | - php: 8.0 22 | env: SYMFONY_VERSION="6.1.*" 23 | - php: 8.1 24 | env: SYMFONY_VERSION="6.1.*" 25 | allow_failures: 26 | - php: nightly 27 | - env: SYMFONY_VERSION="6@dev" 28 | 29 | sudo: false 30 | 31 | cache: 32 | directories: 33 | - $HOME/.composer/cache 34 | 35 | before_script: 36 | - composer selfupdate 37 | - composer config -g github-oauth.github.com $GITHUB_OAUTH_TOKEN 38 | - composer global require phpunit/phpunit friendsofphp/php-cs-fixer --no-update 39 | - composer global update --prefer-dist --no-interaction 40 | - if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; fi; 41 | - composer update --prefer-dist --no-interaction $COMPOSER_FLAGS 42 | 43 | script: 44 | - make test 45 | 46 | after_success: 47 | - php vendor/bin/coveralls -c .coveralls.yml -v 48 | -------------------------------------------------------------------------------- /Controller/GeneratorController.php: -------------------------------------------------------------------------------- 1 | humanPasswordGenerator = $humanPasswordGenerator; 58 | $this->hybridPasswordGenerator = $hybridPasswordGenerator; 59 | $this->computerPasswordGenerator = $computerPasswordGenerator; 60 | $this->requirementPasswordGenerator = $requirementPasswordGenerator; 61 | $this->dummyPasswordGenerator = $dummyPasswordGenerator; 62 | $this->formFactory = $formFactory; 63 | $this->twigEnvironment = $twigEnvironment; 64 | } 65 | 66 | /** 67 | * Password generator form. 68 | * 69 | * @param Request $request 70 | * @param string|null $mode 71 | * 72 | * @return \Symfony\Component\HttpFoundation\Response 73 | */ 74 | public function formAction(Request $request, ?string $mode = null): Response 75 | { 76 | $mode = $this->getMode($request, $mode); 77 | $passwordGenerator = $this->getPasswordGenerator($mode); 78 | 79 | $passwords = $error = null; 80 | $options = new Options($passwordGenerator); 81 | 82 | $form = $this->buildForm($passwordGenerator, $options, $mode); 83 | 84 | $form->handleRequest($request); 85 | 86 | if ($form->isSubmitted() && $form->isValid()) { 87 | try { 88 | $passwords = $passwordGenerator->generatePasswords($options->getQuantity()); 89 | } catch (CharactersNotFoundException $e) { 90 | $error = 'CharactersNotFoundException'; 91 | } 92 | } 93 | 94 | $content = $this->twigEnvironment->render( 95 | '@HackzillaPasswordGenerator/Generator/form.html.twig', [ 96 | 'form' => $form->createView(), 97 | 'mode' => $mode, 98 | 'passwords' => $passwords, 99 | 'error' => $error, 100 | ] 101 | ); 102 | 103 | return new Response($content); 104 | } 105 | 106 | /** 107 | * Lookup Password Generator Service. 108 | * 109 | * @param string $mode 110 | * 111 | * @return PasswordGeneratorInterface 112 | * 113 | * @throws UnknownGeneratorException 114 | */ 115 | private function getPasswordGenerator($mode): PasswordGeneratorInterface 116 | { 117 | switch ($mode) { 118 | case 'dummy': 119 | return $this->dummyPasswordGenerator; 120 | 121 | case 'computer': 122 | return $this->computerPasswordGenerator; 123 | 124 | case 'human': 125 | return $this->humanPasswordGenerator; 126 | 127 | case 'hybrid': 128 | return $this->hybridPasswordGenerator; 129 | } 130 | 131 | throw new UnknownGeneratorException(); 132 | } 133 | 134 | /** 135 | * Figure out password generator mode. 136 | * 137 | * @param Request $request 138 | * @param string $mode 139 | * 140 | * @return string 141 | */ 142 | private function getMode(Request $request, $mode = null): string 143 | { 144 | if (is_null($mode)) { 145 | switch ($request->query->get('mode')) { 146 | case 'dummy': 147 | case 'human': 148 | case 'hybrid': 149 | case 'computer': 150 | return $request->query->get('mode'); 151 | 152 | default: 153 | return 'computer'; 154 | } 155 | } 156 | 157 | return $mode; 158 | } 159 | 160 | /** 161 | * Build form. 162 | * 163 | * @param PasswordGeneratorInterface $passwordGenerator 164 | * @param Options $options 165 | * @param string $mode 166 | * 167 | * @return \Symfony\Component\Form\Form 168 | */ 169 | private function buildForm(PasswordGeneratorInterface $passwordGenerator, Options $options, $mode = ''): FormInterface 170 | { 171 | return $this->formFactory->create(OptionType::class, $options, [ 172 | 'action' => $this->generateUrl( 173 | 'hackzilla_password_generator_show', 174 | [ 175 | 'mode' => $mode, 176 | ] 177 | ), 178 | 'method' => 'GET', 179 | 'generator' => $passwordGenerator, 180 | ]); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | processConfiguration($configuration, $configs); 26 | 27 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 28 | $loader->load('services.yml'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Entity/Options.php: -------------------------------------------------------------------------------- 1 | passwordGenerator = $passwordGenerator; 17 | } 18 | 19 | public function __get($name): mixed 20 | { 21 | return $this->passwordGenerator->getOptionValue(strtoupper($name)); 22 | } 23 | 24 | public function __set($name, $value): void 25 | { 26 | $this->passwordGenerator->setOptionValue(strtoupper($name), $value); 27 | } 28 | 29 | public function getQuantity(): int 30 | { 31 | return (int) $this->quantity; 32 | } 33 | 34 | public function setQuantity($quantity): void 35 | { 36 | $this->quantity = $quantity; 37 | } 38 | 39 | public function getUppercase(): bool 40 | { 41 | return (bool) $this->__get('uppercase'); 42 | } 43 | 44 | public function setUppercase(bool $uppercase): void 45 | { 46 | $this->__set('uppercase', $uppercase); 47 | } 48 | 49 | public function getLowercase(): bool 50 | { 51 | return (bool) $this->__get('lowercase'); 52 | } 53 | 54 | public function setLowercase(bool $lowercase): void 55 | { 56 | $this->__set('lowercase', $lowercase); 57 | } 58 | 59 | public function getNumbers(): bool 60 | { 61 | return (bool) $this->__get('numbers'); 62 | } 63 | 64 | public function setNumbers(bool $numbers): void 65 | { 66 | $this->__set('numbers', $numbers); 67 | } 68 | 69 | public function getSymbols(): bool 70 | { 71 | return (bool) $this->__get('symbols'); 72 | } 73 | 74 | public function setSymbols(bool $symbols): void 75 | { 76 | $this->__set('symbols', $symbols); 77 | } 78 | 79 | public function getAvoidSimilar(): bool 80 | { 81 | return (bool) $this->__get('avoid_similar'); 82 | } 83 | 84 | public function setAvoidSimilar(bool $symbols): void 85 | { 86 | $this->__set('avoid_similar', $symbols); 87 | } 88 | 89 | public function getLength(): ?int 90 | { 91 | return $this->__get('length'); 92 | } 93 | 94 | public function setLength(?int $symbols): void 95 | { 96 | $this->__set('length', $symbols); 97 | } 98 | 99 | public function getWords(): int 100 | { 101 | return (int) $this->__get('words'); 102 | } 103 | 104 | public function setWords(int $symbols): void 105 | { 106 | $this->__set('words', $symbols); 107 | } 108 | 109 | public function getMin(): int 110 | { 111 | return (int) $this->__get('min'); 112 | } 113 | 114 | public function setMin(int $symbols): void 115 | { 116 | $this->__set('min', $symbols); 117 | } 118 | 119 | public function getMax(): int 120 | { 121 | return (int) $this->__get('max'); 122 | } 123 | 124 | public function setMax(int $symbols): void 125 | { 126 | $this->__set('max', $symbols); 127 | } 128 | 129 | public function getSegmentCount(): int 130 | { 131 | return (int) $this->__get('segment_count'); 132 | } 133 | 134 | public function setSegmentCount(int $segmentCount): void 135 | { 136 | $this->__set('segment_count', $segmentCount); 137 | } 138 | 139 | public function getSegmentLength(): int 140 | { 141 | return (int) $this->__get('segment_length'); 142 | } 143 | 144 | public function setSegmentLength(int $segmentCount): void 145 | { 146 | $this->__set('segment_length', $segmentCount); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Exception/UnknownGeneratorException.php: -------------------------------------------------------------------------------- 1 | add( 29 | 'quantity', 30 | IntegerType::class, 31 | [ 32 | 'label' => 'OPTION_HOW_MANY_PASSWORDS', 33 | ], 34 | ); 35 | 36 | $generator = $options['generator']; 37 | 38 | if (!is_a($generator, PasswordGeneratorInterface::class)) { 39 | return; 40 | } 41 | 42 | foreach ($generator->getOptions() as $key => $option) { 43 | if ( 44 | $generator instanceof HumanPasswordGenerator 45 | && HumanPasswordGenerator::OPTION_LENGTH === $key 46 | ) { 47 | continue; 48 | } 49 | 50 | switch ($option->getType()) { 51 | case Option::TYPE_STRING: 52 | $this->addStringType($builder, $key, $option); 53 | break; 54 | 55 | case Option::TYPE_BOOLEAN: 56 | $this->addBooleanType($builder, $key, $option); 57 | break; 58 | 59 | case Option::TYPE_INTEGER: 60 | $this->addIntegerType($builder, $key, $option); 61 | break; 62 | } 63 | } 64 | } 65 | 66 | /** 67 | * @param FormBuilderInterface $builder 68 | * @param $key 69 | * @param OptionInterface $option 70 | */ 71 | private function addStringType(FormBuilderInterface $builder, $key, OptionInterface $option): void 72 | { 73 | $builder->add( 74 | $builder->create( 75 | strtolower($key), 76 | TextType::class, 77 | [ 78 | 'data' => $option->getValue(), 79 | 'label' => 'OPTION_'.$key, 80 | 'required' => false, 81 | ], 82 | ), 83 | ); 84 | } 85 | 86 | /** 87 | * @param FormBuilderInterface $builder 88 | * @param $key 89 | * @param OptionInterface $option 90 | */ 91 | private function addBooleanType(FormBuilderInterface $builder, $key, OptionInterface $option): void 92 | { 93 | $builder->add( 94 | $builder->create( 95 | strtolower($key), 96 | CheckboxType::class, 97 | [ 98 | 'value' => 1, 99 | 'data' => $option->getValue(), 100 | 'label' => 'OPTION_'.$key, 101 | 'required' => false, 102 | ], 103 | ), 104 | ); 105 | } 106 | 107 | /** 108 | * @param FormBuilderInterface $builder 109 | * @param $key 110 | * @param OptionInterface $option 111 | */ 112 | private function addIntegerType(FormBuilderInterface $builder, $key, OptionInterface $option): void 113 | { 114 | $builder->add( 115 | $builder->create( 116 | strtolower($key), 117 | IntegerType::class, 118 | [ 119 | 'data' => $option->getValue(), 120 | 'label' => 'OPTION_'.$key, 121 | 'required' => false, 122 | ], 123 | ), 124 | ); 125 | } 126 | 127 | /** 128 | * {@inheritdoc} 129 | */ 130 | public function configureOptions(OptionsResolver $resolver): void 131 | { 132 | $resolver->setDefaults( 133 | [ 134 | 'data_class' => Options::class, 135 | 'csrf_protection' => false, 136 | 'generator' => null, 137 | ], 138 | ); 139 | } 140 | 141 | public function getName(): string 142 | { 143 | return $this->getBlockPrefix(); 144 | } 145 | 146 | public function getBlockPrefix(): string 147 | { 148 | return ''; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /HackzillaPasswordGeneratorBundle.php: -------------------------------------------------------------------------------- 1 | = 8.0.2 16 | * [hackzilla/password-generator](https://github.com/hackzilla/password-generator) ^1.3.0 17 | * Symfony ^6.0|^7.0 18 | 19 | 20 | Version Matrix 21 | -------------- 22 | 23 | | Password Generator Bundle | Symfony | PHP | 24 | |---------------------------|------------------------------|----------| 25 | | 6.x | ^6.0 | ^7.0 | >=8.0.2* | 26 | | 5.x | ^4.0 | ^5.0 | ^6.0 | >=7.1* | 27 | | 4.x | ^3.0 | ^4.0 | ^5.0 | >=7.1* | 28 | | 3.x | ^3.0 | ^4.0 | >=7.1 | 29 | | 2.x | ^2.7 | ^3.0 | >=5.5 | 30 | | 1.x | ^2.3 | >=5.3 | 31 | 32 | * Symfony 5.0 requires PHP v7.2+ 33 | * Symfony 6.0 requires PHP v8.0.2+ 34 | * Symfony 7.0 requires PHP v8.2+ 35 | 36 | Installation 37 | ------------ 38 | 39 | Add HackzillaPasswordGeneratorBundle in your composer.json: 40 | 41 | ```yaml 42 | { 43 | "require": { 44 | "hackzilla/password-generator-bundle": "^6.0" 45 | } 46 | } 47 | ``` 48 | 49 | Install Composer 50 | 51 | ``` 52 | curl -sS https://getcomposer.org/installer | php 53 | mv composer.phar /usr/local/bin/composer 54 | ``` 55 | 56 | Now tell composer to download the library by running the command: 57 | 58 | ``` bash 59 | $ composer require hackzilla/password-generator-bundle 60 | ``` 61 | 62 | Composer will install the bundle into your project's `vendor/hackzilla` directory. 63 | 64 | ### Step 2: Enable the bundle 65 | 66 | Enable the bundle in the kernel: 67 | 68 | ``` php 69 | =8.0.2 97 | 98 | Migrating from v4 99 | ----------------- 100 | 101 | Version 5 release is just drops support for Symfony v3. 102 | 103 | Migrating from v3 104 | ----------------- 105 | 106 | Version 4 release is just a version bump. 107 | 108 | Migrating from v2 109 | ----------------- 110 | 111 | Version 3 release is just a version bump. 112 | 113 | 114 | Migrating from v1 115 | ----------------- 116 | 117 | Migration should be straight forward, as much of the changes are related to Symfony v3 118 | 119 | * Upgrade to at least PHP 5.5 120 | * Reference Types by Fully Qualified Class Name (FQCN) (>= Symfony 2.8) 121 | * FormTypes use getBlockPrefix, rather than getName 122 | * OptionType is now a service 123 | * CamelCased services are now lowercase with separator (e.g. hackzilla.password_generator.human.maxWordLength changed to hackzilla.password_generator.human.max_word_length) 124 | * Removed previously deprecated service (hackzilla.password_generator). 125 | 126 | Example Implementation 127 | ---------------------- 128 | 129 | See [Password generator app](https://github.com/hackzilla/password-generator-app) 130 | 131 | 132 | Pull Requests 133 | ------------- 134 | 135 | I'm open to pull requests for additional languages, features and/or improvements. 136 | -------------------------------------------------------------------------------- /Resources/config/routing.yml: -------------------------------------------------------------------------------- 1 | hackzilla_password_generator_form: 2 | path: / 3 | controller: Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController::formAction 4 | 5 | hackzilla_password_generator_human_form: 6 | path: /human 7 | controller: Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController::formAction 8 | defaults: { mode: human } 9 | 10 | hackzilla_password_generator_hybrid_form: 11 | path: /hybrid 12 | controller: Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController::formAction 13 | defaults: { mode: hybrid } 14 | 15 | hackzilla_password_generator_computer_form: 16 | path: /computer 17 | controller: Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController::formAction 18 | defaults: { mode: computer } 19 | 20 | hackzilla_password_generator_show: 21 | path: /{mode} 22 | controller: Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController::generate 23 | -------------------------------------------------------------------------------- /Resources/config/services.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | hackzilla.password_generator.computer.length: 12 3 | 4 | hackzilla.password_generator.human.word_list: /usr/share/dict/words 5 | hackzilla.password_generator.human.word_separator: '-' 6 | hackzilla.password_generator.human.word_count: 3 7 | hackzilla.password_generator.human.min_word_length: 5 8 | hackzilla.password_generator.human.max_word_length: 10 9 | 10 | hackzilla.password_generator.hybrid.segment_count: 4 11 | hackzilla.password_generator.hybrid.segment_length: 3 12 | hackzilla.password_generator.hybrid.segment_separator: '-' 13 | 14 | services: 15 | hackzilla.password_generator.requirement: 16 | class: Hackzilla\PasswordGenerator\Generator\RequirementPasswordGenerator 17 | public: true 18 | 19 | hackzilla.password_generator.dummy: 20 | class: Hackzilla\PasswordGenerator\Generator\DummyPasswordGenerator 21 | public: true 22 | 23 | hackzilla.password_generator.computer: 24 | class: Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator 25 | public: true 26 | calls: 27 | - [setLength, ["%hackzilla.password_generator.computer.length%"]] 28 | 29 | hackzilla.password_generator.human: 30 | class: Hackzilla\PasswordGenerator\Generator\HumanPasswordGenerator 31 | public: true 32 | calls: 33 | - [setWordCount, ["%hackzilla.password_generator.human.word_count%"]] 34 | - [setMinWordLength, ["%hackzilla.password_generator.human.min_word_length%"]] 35 | - [setMaxWordLength, ["%hackzilla.password_generator.human.max_word_length%"]] 36 | - [setWordSeparator, ["%hackzilla.password_generator.human.word_separator%"]] 37 | - [setWordList, ["%hackzilla.password_generator.human.word_list%"]] 38 | 39 | hackzilla.password_generator.hybrid: 40 | class: Hackzilla\PasswordGenerator\Generator\HybridPasswordGenerator 41 | public: true 42 | calls: 43 | - [setSegmentCount, ["%hackzilla.password_generator.hybrid.segment_count%"]] 44 | - [setSegmentLength, ["%hackzilla.password_generator.hybrid.segment_length%"]] 45 | - [setSegmentSeparator, ["%hackzilla.password_generator.hybrid.segment_separator%"]] 46 | 47 | Hackzilla\Bundle\PasswordGeneratorBundle\Form\Type\OptionType: 48 | tags: 49 | - { name: form.type } 50 | 51 | Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController: 52 | public: true 53 | tags: ['controller.service_arguments'] 54 | arguments: 55 | - '@hackzilla.password_generator.human' 56 | - '@hackzilla.password_generator.hybrid' 57 | - '@hackzilla.password_generator.computer' 58 | - '@hackzilla.password_generator.requirement' 59 | - '@hackzilla.password_generator.dummy' 60 | - '@form.factory' 61 | - '@twig' 62 | calls: 63 | - [setContainer, ['@service_container']] 64 | -------------------------------------------------------------------------------- /Resources/translations/messages.bg.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | HEADING_CREATE_PASSWORDS 9 | Генератор на Пароли 10 | 11 | 12 | HEADING_SUB_DESCRIPTION 13 | Улеснете измислянето на пароли: 14 | 15 | 16 | HEADING_PASSWORDS 17 | Пароли 18 | 19 | 20 | HEADING_DESCRIPTION 21 | Лесен за използване онлайн генератор на произволни пароли 22 | 23 | 24 | 25 | 26 | MODE_HUMANS 27 | Хора 28 | 29 | 30 | MODE_COMPUTERS 31 | Компютри 32 | 33 | 34 | MODE_HYBRID 35 | Хибрид 36 | 37 | 38 | MODE_DUMMIES 39 | Макет 40 | 41 | 42 | 43 | 44 | 45 | OPTION_HOW_MANY_PASSWORDS 46 | Колко пароли 47 | 48 | 49 | OPTION_UPPERCASE 50 | Включете главни букви 51 | 52 | 53 | OPTION_LOWERCASE 54 | Включете малки букви 55 | 56 | 57 | OPTION_NUMBERS 58 | Включете числа 59 | 60 | 61 | OPTION_SYMBOLS 62 | Включете символи 63 | 64 | 65 | OPTION_AVOID_SIMILAR 66 | Премахване на повтарящи знаци 67 | 68 | 69 | 70 | 71 | OPTION_SEGMENT_COUNT 72 | Брой сегменти 73 | 74 | 75 | OPTION_SEGMENT_LENGTH 76 | Дължина на сегмента 77 | 78 | 79 | 80 | 81 | OPTION_LENGTH 82 | Дължина на паролата 83 | 84 | 85 | 86 | 87 | OPTION_WORDS 88 | Брой думи 89 | 90 | 91 | OPTION_MIN 92 | Минимална дължина на думата 93 | 94 | 95 | OPTION_MAX 96 | Максимална дължина на думата 97 | 98 | 99 | 100 | 101 | 102 | BUTTON_GENERATE 103 | Генерирай 104 | 105 | 106 | BUTTON_RESET 107 | Изчисти 108 | 109 | 110 | 111 | 112 | 113 | LABEL_CITATION 114 | цитат 115 | 116 | 117 | 118 | 119 | 120 | ERROR_HEADING 121 | Грешка! 122 | 123 | 124 | ERROR_CHARACTERS_NOT_FOUND_EXCEPTION 125 | Изберете някои знаци, които генераторът на пароли да използва 126 | 127 | 128 | ERROR_UNKNOWN 129 | Възникна неизвестна грешка 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Resources/translations/messages.en.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | HEADING_CREATE_PASSWORDS 9 | Password Generator 10 | 11 | 12 | HEADING_SUB_DESCRIPTION 13 | Make passwords easier for: 14 | 15 | 16 | HEADING_PASSWORDS 17 | Passwords 18 | 19 | 20 | HEADING_DESCRIPTION 21 | Easy to use online random password generator 22 | 23 | 24 | 25 | 26 | MODE_HUMANS 27 | Humans 28 | 29 | 30 | MODE_COMPUTERS 31 | Computers 32 | 33 | 34 | MODE_HYBRID 35 | Hybrid 36 | 37 | 38 | MODE_DUMMIES 39 | Dummies 40 | 41 | 42 | 43 | 44 | 45 | OPTION_HOW_MANY_PASSWORDS 46 | How many passwords 47 | 48 | 49 | OPTION_UPPERCASE 50 | Include Uppercase 51 | 52 | 53 | OPTION_LOWERCASE 54 | Include Lowercase 55 | 56 | 57 | OPTION_NUMBERS 58 | Include Numbers 59 | 60 | 61 | OPTION_SYMBOLS 62 | Include Symbols 63 | 64 | 65 | OPTION_AVOID_SIMILAR 66 | Remove Similar Characters 67 | 68 | 69 | 70 | 71 | OPTION_SEGMENT_COUNT 72 | Segment Count 73 | 74 | 75 | OPTION_SEGMENT_LENGTH 76 | Segment Length 77 | 78 | 79 | 80 | 81 | OPTION_LENGTH 82 | Password Length 83 | 84 | 85 | 86 | 87 | OPTION_WORDS 88 | Word Count 89 | 90 | 91 | OPTION_MIN 92 | Minimum Word Length 93 | 94 | 95 | OPTION_MAX 96 | Maximum Word Length 97 | 98 | 99 | 100 | 101 | 102 | BUTTON_GENERATE 103 | Generate 104 | 105 | 106 | BUTTON_RESET 107 | Reset 108 | 109 | 110 | 111 | 112 | 113 | LABEL_CITATION 114 | citation 115 | 116 | 117 | 118 | 119 | 120 | ERROR_HEADING 121 | Error! 122 | 123 | 124 | ERROR_CHARACTERS_NOT_FOUND_EXCEPTION 125 | Select some characters for the password generator to use 126 | 127 | 128 | ERROR_UNKNOWN 129 | An unknown error occurred 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Resources/translations/messages.fr.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | HEADING_CREATE_PASSWORDS 9 | Générateur de mot de passe 10 | 11 | 12 | HEADING_SUB_DESCRIPTION 13 | Faire les mots de passe plus facile pour: 14 | 15 | 16 | HEADING_PASSWORDS 17 | Mots de passe 18 | 19 | 20 | HEADING_DESCRIPTION 21 | Générateur en ligne des mots de passe aléatoires. Facile à utiliser. 22 | 23 | 24 | 25 | 26 | MODE_HUMANS 27 | Les humains 28 | 29 | 30 | MODE_COMPUTERS 31 | Les ordinateurs 32 | 33 | 34 | MODE_HYBRID 35 | Hybride 36 | 37 | 38 | MODE_DUMMIES 39 | Les nuls 40 | 41 | 42 | 43 | 44 | 45 | OPTION_HOW_MANY_PASSWORDS 46 | Combien de mots de passe 47 | 48 | 49 | OPTION_UPPERCASE 50 | Insérer les caractères majuscule 51 | 52 | 53 | OPTION_LOWERCASE 54 | Insérer les caractères miniscule 55 | 56 | 57 | OPTION_NUMBERS 58 | Insérer les chiffres 59 | 60 | 61 | OPTION_SYMBOLS 62 | Insérer les symboles 63 | 64 | 65 | OPTION_AVOID_SIMILAR 66 | Supprimer les caractères presque pareils 67 | 68 | 69 | 70 | 71 | OPTION_SEGMENT_COUNT 72 | Nombre de segments 73 | 74 | 75 | OPTION_SEGMENT_LENGTH 76 | longeur du segment 77 | 78 | 79 | 80 | 81 | OPTION_LENGTH 82 | Longeur du mot de passe 83 | 84 | 85 | 86 | 87 | OPTION_WORDS 88 | Nombre de mots 89 | 90 | 91 | OPTION_MIN 92 | Longeur minimum du mot de passe 93 | 94 | 95 | OPTION_MAX 96 | Longeur maximum du mot de passe 97 | 98 | 99 | 100 | 101 | 102 | BUTTON_GENERATE 103 | Générer 104 | 105 | 106 | BUTTON_RESET 107 | Réinitialiser 108 | 109 | 110 | 111 | 112 | 113 | LABEL_CITATION 114 | citation 115 | 116 | 117 | 118 | 119 | 120 | ERROR_HEADING 121 | Erreur! 122 | 123 | 124 | ERROR_CHARACTERS_NOT_FOUND_EXCEPTION 125 | Sélectionnez des caractères pour que le générateur de mot de passe puisse les utiliser 126 | 127 | 128 | ERROR_UNKNOWN 129 | Une erreur inconnue s'est produite 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Resources/views/Generator/computer-layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@HackzillaPasswordGenerator\\layout.html.twig' %} 2 | 3 | {% block layout %} 4 | {% include '@HackzillaPasswordGenerator\\menu.html.twig' with {'mode': mode} %} 5 | {% block form %}{% endblock form %} 6 | {% endblock layout %} 7 | -------------------------------------------------------------------------------- /Resources/views/Generator/form.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@HackzillaPasswordGenerator\\Generator\\' ~ mode ~ '-layout.html.twig' %} 2 | 3 | {% block form %} 4 | {{ form_start(form) }} 5 | {{ form_errors(form) }} 6 | {{ form_rest(form) }} 7 | 8 |
9 | 10 | 11 |
12 | {{ form_end(form) }} 13 | 14 | {% if error %} 15 | 24 | {% endif %} 25 | 26 | {% if passwords %} 27 |
28 |

{{ "HEADING_PASSWORDS"|trans }}

29 | 34 |
35 | {% endif %} 36 | {% endblock form %} 37 | -------------------------------------------------------------------------------- /Resources/views/Generator/human-layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@HackzillaPasswordGenerator\\layout.html.twig' %} 2 | 3 | {% block layout %} 4 | {% include '@HackzillaPasswordGenerator\\menu.html.twig' with {'mode': mode} %} 5 | {% block form %}{% endblock form %} 6 | {% endblock layout %} 7 | -------------------------------------------------------------------------------- /Resources/views/Generator/hybrid-layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@HackzillaPasswordGenerator\\layout.html.twig' %} 2 | 3 | {% block layout %} 4 | {% include '@HackzillaPasswordGenerator\\menu.html.twig' with {'mode': mode} %} 5 | {% block form %}{% endblock form %} 6 | {% endblock layout %} 7 | -------------------------------------------------------------------------------- /Resources/views/layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'base.html.twig' %} 2 | 3 | {% block body %} 4 |

{{ 'HEADING_CREATE_PASSWORDS'|trans }}

5 |

{{ 'HEADING_DESCRIPTION'|trans }}

6 | 7 | {% block layout %} 8 | {% endblock layout %} 9 | {% endblock body %} 10 | -------------------------------------------------------------------------------- /Resources/views/menu.html.twig: -------------------------------------------------------------------------------- 1 |
2 |

{{ 'HEADING_SUB_DESCRIPTION'|trans }} [{{ 'LABEL_CITATION'|trans }}]

3 | {{ 'MODE_HUMANS'|trans }} 5 | {{ 'MODE_COMPUTERS'|trans }} 7 | {{ 'MODE_HYBRID'|trans }} 9 |
10 | -------------------------------------------------------------------------------- /Tests/Controller/GeneratorControllerTest.php: -------------------------------------------------------------------------------- 1 | =')) { 28 | $container = static::getContainer(); 29 | } else { 30 | $container = static::$kernel->getContainer(); 31 | } 32 | 33 | $this->_object = new \Hackzilla\Bundle\PasswordGeneratorBundle\Controller\GeneratorController( 34 | new HumanPasswordGenerator(), 35 | new HybridPasswordGenerator(), 36 | new ComputerPasswordGenerator(), 37 | new RequirementPasswordGenerator(), 38 | new DummyPasswordGenerator(), 39 | $container->get('form.factory'), 40 | $container->get('twig'), 41 | ); 42 | } 43 | 44 | /** 45 | * Call protected/private method of a class. 46 | * 47 | * @param object &$object Instantiated object that we will run method on 48 | * @param string $methodName Method name to call 49 | * @param array $parameters Array of parameters to pass into method 50 | * 51 | * @return mixed Method return 52 | */ 53 | private function invokeMethod(&$object, $methodName, array $parameters = []) 54 | { 55 | $reflection = new \ReflectionClass(get_class($object)); 56 | $method = $reflection->getMethod($methodName); 57 | $method->setAccessible(true); 58 | 59 | return $method->invokeArgs($object, $parameters); 60 | } 61 | 62 | public function testGetPasswordGeneratorException(): void 63 | { 64 | $container = $this->createMock(ContainerInterface::class); 65 | 66 | $container 67 | ->method('get') 68 | ->will( 69 | $this->returnCallback( 70 | function ($service) { 71 | return $service; 72 | } 73 | ) 74 | ); 75 | 76 | $this->_object->setContainer($container); 77 | 78 | $this->expectException(UnknownGeneratorException::class); 79 | $this->invokeMethod($this->_object, 'getPasswordGenerator', ['non-existent']); 80 | } 81 | 82 | public function modeProvider() 83 | { 84 | return [ 85 | ['dummy', 'dummy'], 86 | ['computer', 'computer'], 87 | ['human', 'human'], 88 | ['hybrid', 'hybrid'], 89 | ['', ''], 90 | ]; 91 | } 92 | 93 | /** 94 | * @dataProvider modeProvider 95 | * 96 | * @param string $mode 97 | * @param string $check 98 | */ 99 | public function testGetMode($mode, $check): void 100 | { 101 | $request = new \Symfony\Component\HttpFoundation\Request(['mode' => $mode]); 102 | $returnValue = $this->invokeMethod($this->_object, 'getMode', [$request, $mode]); 103 | 104 | $this->assertSame($check, $returnValue); 105 | } 106 | 107 | public function nullModeProvider() 108 | { 109 | return [ 110 | ['dummy', 'dummy'], 111 | ['computer', 'computer'], 112 | ['human', 'human'], 113 | ['hybrid', 'hybrid'], 114 | ['', 'computer'], 115 | ]; 116 | } 117 | 118 | /** 119 | * @dataProvider nullModeProvider 120 | * 121 | * @param string $mode 122 | * @param string $check 123 | */ 124 | public function testGetModeNull($mode, $check): void 125 | { 126 | $request = new \Symfony\Component\HttpFoundation\Request(['mode' => $mode]); 127 | 128 | $returnValue = $this->invokeMethod($this->_object, 'getMode', [$request, null]); 129 | 130 | $this->assertSame($check, $returnValue); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /Tests/Entity/OptionsTest.php: -------------------------------------------------------------------------------- 1 | _object = new \Hackzilla\Bundle\PasswordGeneratorBundle\Entity\Options($passwordGenerator); 15 | } 16 | 17 | public function quantityProvider() 18 | { 19 | return [ 20 | [1, 1], 21 | [10, 10], 22 | [100, 100], 23 | ['', 0], 24 | ['test', 0], 25 | ]; 26 | } 27 | 28 | /** 29 | * @dataProvider quantityProvider 30 | * 31 | * @param mixed $quantity 32 | * @param int $check 33 | */ 34 | public function testQuantity($quantity, $check): void 35 | { 36 | $this->_object->setQuantity($quantity); 37 | 38 | $this->assertSame($check, $this->_object->getQuantity()); 39 | } 40 | 41 | public function optionProvider() 42 | { 43 | return [ 44 | ['LENGTH', 1], 45 | ['LenGTh', 10], 46 | ['length', 100], 47 | ]; 48 | } 49 | 50 | /** 51 | * @dataProvider optionProvider 52 | * 53 | * @param string $key 54 | * @param mixed $value 55 | */ 56 | public function testOption($key, $value): void 57 | { 58 | $this->_object->{$key} = $value; 59 | 60 | $this->assertSame($value, $this->_object->{$key}); 61 | } 62 | 63 | public function testOptionFailure(): void 64 | { 65 | $this->expectException(\InvalidArgumentException::class); 66 | 67 | $this->_object->{'non_existent'}; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Tests/Form/Type/OptionTypeTest.php: -------------------------------------------------------------------------------- 1 | setValue(true); 21 | 22 | $type = new OptionType(); 23 | 24 | $this->invokeMethod( 25 | $type, 26 | 'addBooleanType', 27 | [ 28 | $this->formBuilder(), 29 | 'key', 30 | $option, 31 | ] 32 | ); 33 | 34 | // Did we we make it here without crashing. 35 | $this->assertTrue(true); 36 | } 37 | 38 | public function testAddStringType(): void 39 | { 40 | $option = new StringOption(); 41 | $option->setValue('test'); 42 | 43 | $type = new OptionType(); 44 | 45 | $this->invokeMethod( 46 | $type, 47 | 'addStringType', 48 | [ 49 | $this->formBuilder(), 50 | 'key', 51 | $option, 52 | ] 53 | ); 54 | 55 | // Did we we make it here without crashing. 56 | $this->assertTrue(true); 57 | } 58 | 59 | public function testAddIntegerType(): void 60 | { 61 | $option = new IntegerOption(); 62 | $option->setValue(123); 63 | 64 | $type = new OptionType(); 65 | 66 | $this->invokeMethod( 67 | $type, 68 | 'addIntegerType', 69 | [ 70 | $this->formBuilder(), 71 | 'key', 72 | $option, 73 | ] 74 | ); 75 | 76 | // Did we we make it here without crashing. 77 | $this->assertTrue(true); 78 | } 79 | 80 | private function formBuilder() 81 | { 82 | $dispatcher = new EventDispatcher(); 83 | 84 | return new FormBuilder('test', null, $dispatcher, $this->factory); 85 | } 86 | 87 | /** 88 | * Call protected/private method of a class. 89 | * 90 | * @param object &$object Instantiated object that we will run method on 91 | * @param string $methodName Method name to call 92 | * @param array $parameters Array of parameters to pass into method 93 | * 94 | * @return mixed Method return 95 | */ 96 | private function invokeMethod(&$object, $methodName, array $parameters = []) 97 | { 98 | $reflection = new \ReflectionClass(get_class($object)); 99 | $method = $reflection->getMethod($methodName); 100 | $method->setAccessible(true); 101 | 102 | return $method->invokeArgs($object, $parameters); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Tests/PublicService.php: -------------------------------------------------------------------------------- 1 | getDefinitions() as $id => $definition) { 26 | $this->checkForService($id, $definition); 27 | } 28 | foreach ($container->getAliases() as $id => $definition) { 29 | $this->checkForService($id, $definition); 30 | } 31 | } 32 | 33 | private function checkForService(string $id, $definition) 34 | { 35 | foreach (self::SERVICES as $service) { 36 | if (stripos($id, $service) === 0) { 37 | $definition->setPublic(true); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Tests/TestKernel.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace Hackzilla\Bundle\PasswordGeneratorBundle\Tests; 15 | 16 | use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; 17 | use Symfony\Component\Config\Loader\LoaderInterface; 18 | use Symfony\Component\DependencyInjection\Compiler\PassConfig; 19 | use Symfony\Component\DependencyInjection\ContainerBuilder; 20 | use Symfony\Component\HttpKernel\Kernel; 21 | use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; 22 | use Symfony\Component\Routing\RouteCollectionBuilder; 23 | 24 | if (\Symfony\Component\HttpKernel\Kernel::MAJOR_VERSION >= 5) { 25 | trait ConfigureRoutes 26 | { 27 | protected function configureRoutes(RoutingConfigurator $routes): void 28 | { 29 | $routes->import(__DIR__.'/routes.yaml', 'yaml'); 30 | } 31 | } 32 | 33 | trait KernelDirectories 34 | { 35 | public function getCacheDir(): string 36 | { 37 | return $this->getBaseDir().'cache'; 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function getLogDir(): string 44 | { 45 | return $this->getBaseDir().'log'; 46 | } 47 | } 48 | } else { 49 | trait ConfigureRoutes 50 | { 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | protected function configureRoutes(RouteCollectionBuilder $routes) 55 | { 56 | $routes->import(__DIR__.'/routes.yaml', '/', 'yaml'); 57 | } 58 | } 59 | 60 | trait KernelDirectories 61 | { 62 | public function getCacheDir() 63 | { 64 | return $this->getBaseDir().'cache'; 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | public function getLogDir() 71 | { 72 | return $this->getBaseDir().'log'; 73 | } 74 | } 75 | } 76 | 77 | /** 78 | * @author Javier Spagnoletti 79 | * @author Daniel Platt 80 | */ 81 | final class TestKernel extends Kernel 82 | { 83 | use ConfigureRoutes, KernelDirectories, MicroKernelTrait { 84 | ConfigureRoutes::configureRoutes insteadof MicroKernelTrait; 85 | KernelDirectories::getCacheDir insteadof MicroKernelTrait; 86 | KernelDirectories::getLogDir insteadof MicroKernelTrait; 87 | } 88 | 89 | public function __construct() 90 | { 91 | parent::__construct('test', true); 92 | } 93 | 94 | /** 95 | * {@inheritdoc} 96 | */ 97 | public function registerBundles(): array 98 | { 99 | return [ 100 | new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), 101 | new \Symfony\Bundle\TwigBundle\TwigBundle(), 102 | ]; 103 | } 104 | 105 | public function build(ContainerBuilder $container): void 106 | { 107 | $container->addCompilerPass(new PublicService(), PassConfig::TYPE_OPTIMIZE); 108 | parent::build($container); 109 | } 110 | 111 | /** 112 | * {@inheritdoc} 113 | */ 114 | protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) 115 | { 116 | // FrameworkBundle config 117 | $frameworkConfig = [ 118 | 'secret' => 'MySecretKey', 119 | 'default_locale' => 'en', 120 | 'form' => null, 121 | 'test' => true, 122 | ]; 123 | 124 | if (version_compare(self::VERSION, '5.1', '>=') && version_compare(self::VERSION, '6.0', '<')) { 125 | $frameworkConfig['router'] = ['utf8' => true]; 126 | } 127 | 128 | $c->loadFromExtension('framework', $frameworkConfig); 129 | 130 | // TwigBundle config 131 | $twigConfig = [ 132 | 'strict_variables' => '%kernel.debug%', 133 | 'exception_controller' => null, 134 | ]; 135 | // "default_path" configuration is available since version 3.4. 136 | if (version_compare(self::VERSION, '3.4', '>=')) { 137 | $twigConfig['default_path'] = __DIR__.'/Resources/views'; 138 | } 139 | $c->loadFromExtension('twig', $twigConfig); 140 | } 141 | 142 | private function getBaseDir() 143 | { 144 | return sys_get_temp_dir().'/hackzilla-password-generator-bundle/var/'; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ./ 18 | 19 | 20 | 21 | ./Resources 22 | ./Tests 23 | ./vendor 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | ./Tests 38 | 39 | 40 | 41 | 42 | --------------------------------------------------------------------------------