Project Link (sandbox with description, screenshots as below..)

https://www.drupal.org/sandbox/skaught/2692853

  • creates a block and related admin content addiction/edit/ordering/delete interfaces to display a developers skill to be shown on a portfolio site.
  • enable and goto /admin/content/skillset-inview to begin! link on module page
  • place block to a region when skill items are ready!
  • hook_help details /admin/help/skillset_inview
  • Please do see for more general description, requirements, setup. etc.. Please do comment on those instructions if not clear!!
  • README with instructions within 'module' folder. Requirements checked and instructions given during module enable.

Live example:

goodscott.com -- near bottom of page above contact form. notice bars grow once it's 'inview' (:

Project Repo

git clone --branch 7.x-1.x git://git.drupal.org/sandbox/SKAUGHT/2692853.git skillset_inview
git clone --branch 8.x-1.x git://git.drupal.org/sandbox/SKAUGHT/2692853.git skillset_inview

7x / 8.x differences:

8.x branch has two additional features.

  1. alpha sort button on ordering (Overview) UI
  2. Skill Color Tab. user can customize colors through UI to match their theme.

Manual reviews of other projects

Comments

SKAUGHT created an issue. See original summary.

skaught’s picture

Issue summary: View changes
PA robot’s picture

Status: Active » Needs work

There are some errors reported by automated review tools, did you already check them? See http://pareview.sh/pareview/httpgitdrupalorgsandboxSKAUGHT2692853git

We are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will take a look at your project right away :-)

Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).

I'm a robot and this is an automated message from Project Applications Scraper.

skaught’s picture

Status: Needs work » Needs review

have applied Coder and pareview.sh error.

a few conditions of pareview in .module have been skipped as they broke php.

406 | WARNING | [x] A comma should follow the last multiline array item.
| | Found: )
406 | ERROR | [x] Array closing indentation error, expected 6 spaces
| | but found 8
513 | WARNING | [x] A comma should follow the last multiline array item.
| | Found: )
543 | WARNING | [x] A comma should follow the last multiline array item.
| | Found: ]

also in .tpl -- these are now parsed before they are saved to dbase..but i can't bypass note.

29 | WARNING | [ ] Only string literals should be passed to t() where
| | possible
35 | WARNING | [ ] Only string literals should be passed to t() where
| | possible
skaught’s picture

Status: Needs review » Fixed
skaught’s picture

Status: Fixed » Needs review

reset tag

romanblanyar’s picture

Hello, I have installed and tested your module. When I try to ыset Section Title in the module settings get this errors:
Notice: Undefined index: skill_item in skillset_inview_form_submit() (line 534 of C:\xampp\htdocs\drupal\sites\all\modules\skillset_inview\skillset_inview.module).
Warning: Invalid argument supplied for foreach() in skillset_inview_form_submit() (line 534 of C:\xampp\htdocs\drupal\sites\all\modules\skillset_inview\skillset_inview.module).

skaught’s picture

good catch.. i've just run through with a clean install and see you've submitted the form without first adding any 'skill'.

I've added a routine to detect empty on submit.
thanks.

skaught’s picture

last error from pareview.sh:

FILE: ...www/drupal-7-pareview/pareview_temp/templates/skillset-inview.tpl.php
---------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
---------------------------------------------------------------------------
36 | ERROR | Printing unsanitized input from node title

this is passed through filter_css on skillset_inview_form_submit() [see line 555]
as are 'skill titles' on line 563 -- which this has now cleared with t() on tpl.
So i'm not sure how else to fix/bypass this an a notice.

skaught’s picture

Issue summary: View changes
skaught’s picture

#9, have address by renaming db field (from 'title' to 'name') seems as though it's just trying to protect $obj->title too vigorously due to generaic use of ->title

skaught’s picture

StatusFileSize
new77 KB
new167.28 KB
skaught’s picture

Title: [d7] skillset_inview » [d8] & [d7] Skillset Inview
Issue summary: View changes
skaught’s picture

Issue summary: View changes
skaught’s picture

Issue summary: View changes
skaught’s picture

Issue summary: View changes
skaught’s picture

Issue summary: View changes
Issue tags: +PAreview: review bonus
skaught’s picture

Issue summary: View changes
skaught’s picture

Issue summary: View changes
skaught’s picture

StatusFileSize
new78.94 KB
skaught’s picture

Issue summary: View changes
skaught’s picture

Issue summary: View changes
th_tushar’s picture

Status: Needs review » Needs work
Issue tags: +PAreview: security

Hi @SKAUGHT,

I have manually reviewed the D7 version of your module,

There is a security vulnerability in your module,

$current .= '<li>' . $item->name . ' <span>' . $item->percent . '%</span></li>' . PHP_EOL;

$item->name in skillset_inview_add_form function of .module file should be passed through check_plain function.

Would review the code again to find more such issues. Changing the status to "Needs work".

skaught’s picture

those items are pulled from the database. And 'name' is pre run thru xss_filter on submit, percent is an int field (taken thro a Range field). Display in on an admin panel with module permission. Is seen on /admin/content/skillset-inview/add -- quick list for content admin to see all items while adding new.

name output will contain html, check_plain would break that output.

skaught’s picture

Status: Needs work » Needs review
th_tushar’s picture

Status: Needs review » Needs work

Hi @SKAUGHT,

The user entered fields should be stored as is in the database. When user edits the field, he should get what he has entered. The value should be sanitized before displaying it back to user. So, please fix the issue as per comment #23.

skaught’s picture

Status: Needs work » Needs review

...fields should be stored as is in the database.

sorry, NO. that is a security break. data should always be pre filtered before stored.


When user edits the field, he should get what he has entered.

that's a UX request. wont' fix.
current UX flow is: ..after uses 'saves' that is then shown in the list before. and is then clean to add another new item. a notice of new item added is given by drupal_set_message at that point.

cheers.

th_tushar’s picture

Status: Needs review » Needs work

When handling data, the golden rule is to store exactly what the user typed. When a user edits a post they created earlier, the form should contain the same things as it did when they first submitted it. This means that conversions are performed when content is output, not when saved to the database

Thanks.

skaught’s picture

Status: Needs work » Needs review

sorry, i will not subscribe to that 'golden rule'. that is a matter of option. i will continue to follow this other 'golden rule' thanks.

Again, as the field does contain html (as seen in the ALLOWED HTML description below the input field, We do want to make sure that it is only what is expected —— AND, that is is not broken html.

WORKS AS DESIGNED.

skaught’s picture

Issue tags: -PAreview: security

In earnestness to #23. have wrapped $item->name with additional filter_xss()

7.x branch — commit id: dc9b30bf00b8dbde9e347233792ac79059aba525
8.x branch — commit id: 89746dc1387bb7005bfe62333ca0d697fdc245b

FIXED

skaught’s picture

@th_tushar

Of course, thank you for your review. But I do hope you extend your own process for pre-filtering data. unfiltered data going in could include <script> tags... SQL injections etc.



Best general 'golden rule' would be it to 'take it from both ends'.

skaught’s picture

7.x & 8.x line:
touchup resulting from #29 -- add form_error trigger to notify uses of broken HTML (did just fix without giving user chance to correct their mistake) @UX_love


d7 line — edit/order page
  • have backported DupCheck from 8.x line
  • add ID's inline with order form so resulting errors have some way to let user know which fields are in error

@a11y (as Drupal 7 lacks INLINE FORM ERRORS -- rework error notes as can best do..)

skaught’s picture

Issue summary: View changes
skaught’s picture

StatusFileSize
new105.54 KB

add skillbar color to 8.x line.. pic attached.

skaught’s picture

StatusFileSize
new102.35 KB

nicer sample colors

skaught’s picture

Issue summary: View changes
skaught’s picture

StatusFileSize
new136.87 KB

silly me! lost sight of farbtastic being included by core (color). have reworked 8.x to use it.

16million colors — knock yourself out!

skaught’s picture

Issue summary: View changes
klausi’s picture

Status: Needs review » Needs work

manual review of the 8.x branch:

  1. the drupal 8 branch shows quite a few coding standard errors: http://pareview.sh/pareview/httpgitdrupalorgsandboxskaught2692853git
  2. Unescape.php: why is this extension needed? Please describe that on the doc block of the class. What is the use case?
  3. SkillsetInviewPreviewController: don't use global functions like db_select() or render() or \Drupal in classes. Always inject your dependencies, see https://www.drupal.org/node/2133171 . Same in SkillsetInviewAddForm.
  4. SkillsetInviewPreviewController: don't use t() in controillers, use $this->t() instead.
  5. SkillsetInviewAddForm::submitForm(): the submitted skill name is user provided text, so you should use the "@" or "%" placeholder with drupal_set_message(). I think the "!" placeholder does not even existing anymore in Drupal 8, right?
  6. "t('@color is not a valid hexadecimal color.', ['@color' => Html::escape($values[$item])]))": no need to escape the value here, the "@" placeholder with t() will already do that for you. Make sure to read https://www.drupal.org/node/28984 again.
  7. SkillsetInviewColorForm: why do you need to call drupal_flush_all_caches() here? How can your module affect each and every cache? Please add a comment in the code?
  8. SkillsetInviewColorForm: why is there a script tag with document.write()? You can jsut include your text in the render array?
  9. "'#title' => 'Inside Percent',": all user facing text must run through $this->t() for translation. Make sure to check all your strings.
  10. Your classes like SkillsetInviewOrderForm are quite long because you repeat the module name in the class name. That is not necessary anymore in Drupal 8 because we have namespaces now anyway.
  11. "t("Delete skill '@name'", ['@name' => trim(strip_tags(Html::normalize($row->name)))])": why is the strip_tags() necessary here? The "@placeholder will sanitize for you and just create an escaped version anyway. I think that whole "trim(strip_tags(Html::normalize()" wrapping can be removed.
  12. SkillsetInviewOrderForm::alphaSort(): Do not use Xss::filter() here since you are not printing anything to HTML. "When handling data, the golden rule is to store exactly what the user typed. When a user edits a post they created earlier, the form should contain the same things as it did when they first submitted it. This means that conversions are performed when content is output, not when saved to the database" from https://www.drupal.org/node/28984

The wrong usage of t() is a blocker right now and you need to know where to apply sanitization and where not.

skaught’s picture

of your more direct points:

2. Unescape.php -- due to twig escaping any input that does that html being passed thru twig' t()...( and pareview, then complaining about using the old '!' placeholder) -- this twig filter was introduced to correct for final render.

3. those are procedural function calls ..I've had no warning about missing DI..so i'm not aware of what to specifically add beyond what 'is there now'. please clarify missing DI statements (pareview also doesn't note this..)

7. final block (once placed in a theme/region) is not updated after a order change, nor after color update) -- thus cache flush was added to due so.

8. document.write --> if uses browser does not have JS on...then color picker will not be there...therefore instruction to use is not needed @JS_DEGRADE_STATE @works_as_designed

10. (shorter function names) yes..a nice to have... due to porting from D7 originally and 'keeping things similar' still.

11 @works_as_designed [ i think that sample is coming from one of the validate functions}.. i'm striping input down to match for duplicate, or checking from broken html. keeping in mind i am 'allowing tags' .. and only those. i'm keeping control over that. (and ties to point 12)

12. @works_as_designed -- as from my above conversation @th_tushar -- not prefiltering data is a bad golden rule. 'take it from both ends' .. my user is made aware that they have broken html, or dis-allowed tags (: @UX @BETTER_data_handling

1.4.5,6,9 --in short order(similar points), will address shortly..
i'm just waking up and having some coffee right now.. will updated ticket status when re-work is complete. thanks!

klausi’s picture

dependency injection: every time you are using \Drupal in a class you are doing it wrong. There are some exceptions, but most of the time it is possible to pass in services that you need through the constructor. https://www.drupal.org/node/2133171 has an intro on that and you can look at many examples in core that do it.

skaught’s picture

i do get what you mean...

a quick aside:
it's actually confusing because #2133171 actually makes it look like "it's okay to do this", and there certainly are enough code samples floating everywhere that do this..

// Returns a Drupal\Core\Database\Connection object.
$connection = \Drupal::database();
$result = $connection->select('node', 'n')
  ->fields('n', array('nid'))
  ->execute();

so: it seems like i should just use \Drupal as the comment is 'returns a Drupal\Core\Database\Connection object'


the sample doesn't provide a secondary example showing this proper use statement.

skaught’s picture

in progress note:

#39 point5
<q>@name</q> is a replica. !links', array('@name' => $name, '!links' => $links)));
can not replace '!' with '@'
links are for @a11y related error message links (duplicate names were entered). yes, ! is not suppose to exist, but does. again, can't replace as output is then broken.

skaught’s picture

StatusFileSize
new107.1 KB

comment 43 visual

skaught’s picture

@klausi

have replaced db_select() and render(). Admittedly, i'm still fuzzy on DI use.. please provide any clearer samples should these changes not be enough.

as well as other points have been addressed, commit comments follow bullet points from #39.

skaught’s picture

Status: Needs work » Needs review
skaught’s picture

also, i've added my 2cents against Handle text in a secure fashion this golden rule is garbage!

document is already noted as 'needing update' -- indeed it does. aim for better practice.

klausi’s picture

Assigned: Unassigned » mpdonadio
Status: Needs review » Reviewed & tested by the community

manual review:

  1. SkillsetInviewAddForm: class comment is useless and only repeats the name. It should say what thew class doesm for example: "Provides a form to create a new skill item." or similar.
  2. \Drupal::database() is wrong in a form class. Again, you are using the global \Drupal, but you should use somehting like $this->databseConnection() and inject that in the constructor. The documentation only suggests \Drupal for use in static functions. https://www.drupal.org/node/2203931 gives an example how to inject dependencies into a form. Please check that for all your form classes.
  3. SkillsetInviewAddForm::submitForm(): still sanitizes the data to be saved to the database, which you should not do. It is perfectly fine to validate data in a validation handler, but once you are in a submission handler you should take the data as given and save it unaltered. Can you check all your submit handlers that they store the data unchanged in the database? Validation should be done in a validation handler.
  4. SkillsetInviewColorForm: "Skillset Heading" all user facing text must run through $this->t() for translation.
  5. "$this->t("Delete skill '@name'", ['@name' => trim(strip_tags(Html::normalize($row->name)))]),": why the strip_tags() here and the normalize call? Can you add a comment in the code why this is necessary or remove that?

But that are not critical application blockers, otherwise RTBC.

Assiging to mpdonadio as he might have time to take a final look at this.

mpdonadio’s picture

Are we reviewing both the D7 and D8 branches, or just the D8 one?

And, I have read the chain here. Though you may not agree with it, save as-is and sanitize on output / use DB placeholders is the Drupal way of handling things, and is a perfectly acceptable from a security standpoint. Personally, I find this much easier and less error prone than scrubbing user input.

skaught’s picture

thanks.
I will fix t() related notes shortly. and continue revising the DI issues as i get my head deeper into it.

skaught’s picture

@mpdonadio
..ideally both branches. klausi did just look at 8. th_tushar reviewed 7

the 'difference' between 7 & 8 is --> 8 has both the 1)theme color picker, and 2)alpha sort functions (on order form).

basically, i wrote the 7 line first.. and just in increasing my D8 learning curve got the ideas for alpha sort and user color.. so i just haven't back-ported. (maybe as an incentive to use d8) [ Of course, otherwise a themer can do as they will with the tpl and standard theme override methods..]

skaught’s picture

one more thought about filtering on submits:
it's always a better practive to filter on sumbit as well. WHAT IF: someone/somehow alters your validation routine? then you end up with corrupt data.

even though this is a permission based form... i'ld rather be aggressively proactive. and in the real world: i'ld like to not be sued by a client for a lazy practice.

skaught’s picture

#48 point4-- t() wrapped fixed.
#48 point5-- end user message confirms that 'skill name' has been deleted -- this is page title and if name 'had' html in it then it is output escaped, thus html is removed.

skaught’s picture

StatusFileSize
new8.31 KB

#53 related image-- delete has been done confirmation message. comment added to code.

mpdonadio’s picture

Automated Review

Review of the 8.x-1.x branch (commit 7878c40):

  • Coder Sniffer has found some issues with your code (please check the Drupal coding standards). See attachment.
  • ESLint has found some issues with your code (please check the JavaScript coding standards).
    /Users/matt/PAR/pareview_temp/js/skillset-inview-color.js: line 6, col 1, Error - Definition for rule 'keyword-spacing' was not found (keyword-spacing)
    /Users/matt/PAR/pareview_temp/js/skillset-inview-percent_assist.js: line 6, col 1, Error - Definition for rule 'keyword-spacing' was not found (keyword-spacing)
    /Users/matt/PAR/pareview_temp/js/skillset-inview.js: line 6, col 1, Error - Definition for rule 'keyword-spacing' was not found (keyword-spacing)
    
    3 problems
    
  • No automated test cases were found, did you consider writing Simpletests or PHPUnit tests? This is not a requirement but encouraged for professional software development.

This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. You have to get a review bonus to get a review from me.


FILE: /Users/matt/PAR/pareview_temp/skillset_inview.install
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 39 | ERROR | [x] Expected 1 blank line after function; 2 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: /Users/matt/PAR/pareview_temp/skillset_inview.module
----------------------------------------------------------------------
FOUND 5 ERRORS AFFECTING 5 LINES
----------------------------------------------------------------------
 22 | ERROR | [x] Expected 1 blank line after function; 2 found
 43 | ERROR | [x] Expected 1 blank line after function; 2 found
 51 | ERROR | [x] Expected 1 blank line after function; 2 found
 66 | ERROR | [x] Expected 1 blank line after function; 2 found
 83 | ERROR | [x] Expected 1 blank line after function; 2 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 5 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: /Users/matt/PAR/pareview_temp/src/Form/SkillsetInviewAddForm.php
----------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
  24 | ERROR | [x] Expected 1 blank line after function; 2 found
 112 | ERROR | [x] Expected 1 blank line after function; 2 found
 147 | ERROR | [x] Expected 1 blank line after function; 2 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: /Users/matt/PAR/pareview_temp/src/Form/SkillsetInviewColorForm.php
------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
------------------------------------------------------------------------
 359 | ERROR | [x] Expected 1 blank line after function; 2 found
------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
------------------------------------------------------------------------


FILE: /Users/matt/PAR/pareview_temp/src/Form/SkillsetInviewDeleteForm.php
-------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
-------------------------------------------------------------------------
 82 | WARNING | Line exceeds 80 characters; contains 81 characters
-------------------------------------------------------------------------


FILE: /Users/matt/PAR/pareview_temp/src/Form/SkillsetInviewOrderForm.php
------------------------------------------------------------------------
FOUND 8 ERRORS AFFECTING 8 LINES
------------------------------------------------------------------------
 218 | ERROR | [x] Expected 1 blank line after function; 2 found
 226 | ERROR | [x] Expected 1 blank line after function; 2 found
 235 | ERROR | [x] Expected 1 blank line after function; 2 found
 243 | ERROR | [x] Expected 1 blank line after function; 2 found
 263 | ERROR | [x] Expected 1 blank line after function; 2 found
 284 | ERROR | [x] Expected 1 blank line after function; 2 found
 329 | ERROR | [x] Expected 1 blank line after function; 2 found
 370 | ERROR | [x] Expected 1 blank line after function; 2 found
------------------------------------------------------------------------
PHPCBF CAN FIX THE 8 MARKED SNIFF VIOLATIONS AUTOMATICALLY
------------------------------------------------------------------------

Time: 1.65 secs; Memory: 13.75Mb

Manual Review

CSS rule for '.skillset-inview-wrapper: hover' is broken.

In your OO code, inject your services and avoid the \Drupal static service container. This may be the best starting point, https://docs.acquia.com/articles/drupal-8-dependency-injection

The same goes for some of the static factory methods (like Url::fromRoute); there are services for nearly all of those.

Thought you shouldn't be using it in OO code, the convention is to explicitly use the static service container as ``\Drupal` and not `Drupal`.

Convention prefer that `use` blocks are alphabetical.

In render arrays, avoid concatenating markup with strings. See if there is a better render structure, or use #prefix and #suffix.

And, in a render array, avoid rendering things and using #markup. Just stuff them into the render array w/ the right properties.

The render array in SkillsetInviewPreviewController::preview() has a dependency on the user, so you need to add this cache context. Same with SkillsetInviewZero

Doxygen convention in Drupal is to fully qualify class names.

This has been beaten to death, but the Drupal convention is to store user input as-is and handle it properly on output and via database placeholders. Under old-policy this would be consideration for a blocking issue (major API problem), but no longer is.

You are building up an lot of markup on the fly. Consider moving a lot of this to Twig templates.

TBH, there are some head-scratchers security wise. The config variables are used as-is in but have validation.
This HTML is then passed to Markup::create(), which marks the string as safe and then stuffed into a #markup render element. #markup
normally sanitizes via Xss::filterAdmin(), but this is already a safe string so it isn't sanitized. I think these are OK b/c the validation, but I still think it would be
best to handle this complex markup via Twig (Markup really shouldn't be used this way). See https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21... for more info.

Why the full drupal_flush_all_caches() in the forms? Can't you just invalidate the proper render related things?

Typically, static:: is preferred over self:: (cf, PHP late static binding)

The Unescape class should not be needed w/ proper render arrays, theming, and Twig templates. You are just building up too much markup in PHP and not leveraging Drupal to do this for you.

I am not seeing any blocking issues here, but the comments above about Markup::create() and Unescape make me a little unseasy, but I don't see any exploitable vectors right now.

If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.

This review uses the Project Application Review Template.

mpdonadio’s picture

Assigned: mpdonadio » Unassigned
Status: Reviewed & tested by the community » Fixed

Thanks for your contribution, SKAUGHT!

I updated your account so you can promote this to a full project and also create new projects as either a sandbox or a "full" project.

Here are some recommended readings to help with excellent maintainership:

You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and stay involved!

Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

Thanks to the dedicated reviewer(s) as well.

skaught’s picture

thanks!

skaught’s picture

reminder: new pareview testing path
http://git.drupal.org/project/skillset_inview.git

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

avpaderno’s picture

Title: [d8] & [d7] Skillset Inview » [D8] Skillset Inview
Status: Closed (fixed) » Fixed

I am changing status to credit the users who participated on this issue and the duplicate ones. I apologize for bumping this application.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.