Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Authentication overhaul - #129

Merged
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul
Mar 27, 2021
Merged

Authentication overhaul#129
gsnyder2007 merged 13 commits into
blackducksoftware:masterfrom
OffBy0x01:authentication-overhaul

Conversation

@OffBy0x01

Copy link
Copy Markdown
Collaborator

Authentication overhaul providing similar functionality to 118 but using the proper requests auth hook.

Additionally provides request wrapper to provide automatic pagination of applicable resources, header insertion, etc.

Demo of how these can be used in test/demo_client.py.

@mkumykovmkumykov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backward compatibility is not maintained.
This will break every single piecs of code written agains the library, likely causing more work that we can handle. Not good.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

It's been a number of months since I wrote the code for this particular PR but IIRC HubRestApi.py should still work as normal - but if not please let me know. The Client class I reference is intended to be an alternative that can gradually achieve functional parity with the existing HubRestApi client - would require a refactor to large for a single PR.

@mkumykov

Copy link
Copy Markdown
Contributor

@AR-Calder Yes, I have added the import statement into the HubRestApi.py and is seems to be back to functional state.

Functional parity of blackduck.Client with HubRestApi is less critical at the moment than keeping the restructured HubRestApi interface and functionally identical to the existing one.

There are new features that old library, and the code that uses it, can benefit from. And we should try to introduce it as transparently as possible.

Modifying internal structure of the library is pretty much a fair game, as long as the compatibility is maintained.

On the other hand, modifying external facing features of the library should to be based on specific goals that are explicitly stated and verified. It is preferable for modifications to be additive for compatibility reasons.

For example, the re-authentication is at the top of the list to allow for long running programs based on this library.

Our current interface does not allow to talk to multiple instances of a Blackduck without constantly re-initializing HubInstance object.

It would be nice to have a concise justification for the new external interface with benefits and downsides elaborated to sufficient depth. That will allow to maintain focus.

We know the downsides - we have ask our customers to rewrite their code, the code that does not otherwise have problems.

We have to state the upsides - we are changing the library interface dramatically - because it somehow will make users life better in some way

Thoughts?

@OffBy0x01

OffBy0x01 commented Mar 11, 2021

Copy link
Copy Markdown
CollaboratorAuthor

They don't necessarily have to change their existing code - you could leave the existing interface in for backwards compatibility.

Just think for a different approach it would be best to use a new interface, rather than trying to conform to the restrictions of the current one.

  • Personally I'd like the new interface to be more dynamic, by which I mean taking full advantage of HATEOAS - it should be possible to simply provide generic functions e.g. bd.get_resource(name='projects') as opposed to bd.get_projects() , and bd.get_resource(project, 'versions') as opposed to bd.get_project_versions(project).
  • Support for user-controlled http client settings inc proxy.
  • No/less hard-coded headers.
  • As a consequence of the above - API less likely to break with hub updates.
  • Endpoints supporting pagination can return generators directly providing items i.e. do not have to get object['items']; enabling user to do things like for version in bd.get_resource(project, 'versions'): print(version.get('versionName')

These sorts of changes represent a different approach - in my opinion, methods of a given interface should be idiomatic. In this case the cleanest way to achieve this is to create an alternative interface - which also ensures existing projects with this dependency do not break.

Happy to discuss further with you @mkumykov and @gsnyder2007 on a call.

@mkumykov

Copy link
Copy Markdown
Contributor

Agreed, new interface has a promise to be better. And by all means, let's make it better.
Maintaining old interfaces is a shield that will allow sane cadence for new development.

@OffBy0x01

Copy link
Copy Markdown
CollaboratorAuthor

Perhaps it might be best to leave HubRestApi.py as it was and leave the class splitting to the new interface - thoughts?

@mkumykov

Copy link
Copy Markdown
Contributor

I am a bit wary of that approach. We can't drop old code, and we cant create new code fast enough.
It might create resource contention with one of the competing code bases going stale.
I like the approach that you have taken. You can maintain old interface until we decide to drop it.
And you can plug existing methods into the new code and make them useable, while working on better written replacements. An evolutionary approach, if you will.
Exactly what you have done so far. We just put some due diligence tests on top of it and we have a winner.

@gsnyder2007
gsnyder2007 merged commit 42ddff6 into blackducksoftware:masterMar 27, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@OffBy0x01@mkumykov@gsnyder2007