I'm working on a simple JIRA Server plugin that will prevent a transition from occurring if a certain custom field has not been set. I have created a new workflow validator with atlas-create-jira-plugin-module and tailored the validate function to fit my needs. Strangely, when I add this new validator to a transition via the workflow editor, it appears in the list of validations with the wrong description. It is showing the description from the default condition, "Only users with Resolve Issues" permission can execute this transition".
I've been following along with this tutorial: https://developer.atlassian.com/server/jira/platform/creating-workflow-extensions/
I also came across this similar tutorial: https://www.j-tricks.com/tutorials/workflow-validator
In my atlassian-plugin.xml I made sure to define a "view" velocity resource:
<workflow-validator key="custom-field-is-set-validator" name="Custom Field Is Set Validator" i18n-name-key="custom-field-is-set-validator.name" class="com.ngc.jira.plugins.workflow.CustomFieldIsSetValidatorFactory">
<description key="custom-field-is-set-validator.description">Validation to require that a custom field be given a value.</description>
<validator-class>com.ngc.jira.plugins.workflow.CustomFieldIsSetValidator</validator-class>
<resource type="velocity" name="view" location="templates/validators/custom-field-is-set-validator.vm"/>
<resource type="velocity" name="input-parameters" location="templates/validators/custom-field-is-set-validator-input.vm"/>
<resource type="velocity" name="edit-parameters" location="templates/validators/custom-field-is-set-validator-input.vm"/>
</workflow-validator>
And the contents of custom-field-is-set-validator.vm are as follows:
Only if the custom field <strong>$field</strong> has be set.
As a sanity check, I created a workflow condition and applied my velocity (vm) resource as the view template for it. It shows up correctly within this context!
However, when I try to use the same velocity resource for my workflow validator, the admin page still displays the validator as "Only users with Resolve Issues permission can execute this transition" instead of using my description.
What am I missing? Thanks!
Screenshot showing the built-in condition
Screenshot showing my validator that is wrongly appearing as the same condition
I wrote an O'Reilly book Practical Jira Plugins back in 2011 that has a validator example. The source for this is at https://bitbucket.org/mdoar/practical-jira-plugins/src/default/ (and the book is Out There).
But frankly these days I'd use ScriptRunner, JMWE or other plugins that let you write custom workflow things. But don't let that stop you learning it! Good luck
It turns out, I had copied/pasted a piece of code from my workflow condition that needed to be tweaked for a workflow validator. I was trying to cast to a ConditionDescriptor when I should have been casting to a ValidatorDescriptor:
Bad:
if (!(descriptor instanceof ConditionDescriptor)) {
throw new IllegalArgumentException("Descriptor must be a ConditionDescriptor.");
}
ConditionDescriptor conditionDescriptor = (ConditionDescriptor) descriptor;
Good:
if (!(descriptor instanceof ValidatorDescriptor)) {
throw new IllegalArgumentException("Descriptor must be a ValidatorDescriptor.");
}
ValidatorDescriptor validatorDescriptor = (ValidatorDescriptor) descriptor;
Pretty neat that instead of completely breaking my plugin, it ended up displaying a different description altogether. ;)
Related
The current implementation of a CCDA generator I'm working on, prints a message on a <name> tag (in header sections, where no <text> is available) when something's name is not found:
<name>No information</name>
I know the right way to express not found information is through the #nullFlavor attribute:
<name nullFlavor="NI" />
But right now there is a component on the application that reads the value on the tag and shows it in a human-readable view of the CCDA document. If I use #nullflavor only, the field that shows such name will be empty, instead of "No information".
In order to avoid changing such component, I was thinking on adding the #nullFlavor attribute but still letting the message there:
<name nullFlavor="NI">No information</name>
I know this is syntactically correct, because I've tested it with the reference validator and it passes. My question is: from a semantic point of view, is it valid?
Yes it's valid. The particular specification in question - the v3 abstract data types, simple says:
invariant(ST x) where x.nonNull {
x.headCharacter.notEmpty;
};
So if there's no nullFlavor, there must be some content. But the reverse rule is not applied; there can be content if there's a nullFlavor
Although it is not restricted, my point of view is that it is not a good strategy. I understand that you have a restriction regarding this component but, when you are building a CDA, it is important to keep in mind that it is something to be shared with everyone, and I would never expect to find content inside a nullFlavor attributed element.
We are working on transitioning to Zephyr for JIRA from HP QC/QTP; but a tiny wiggle has presented itself:
When creating a new issue from a test run; the tester has to manually enter version info for the new defect, which on its own is fine, but it's an additional step, and on occasion forgotten.
What we would like then, is for the field "Affects Version/s" to be automatically filled based on either the state of the project, or the sepcific values set in fields in the test.
How can this be achieved?
Allright. You can add custom javascript to JIRA by going to JIRA Administration -> System -> User Interface -> Announcement Banner.
The easiest way is to add a tag linking to your javascript file (wherever it is, must be available to all users. Preferably on the same server as your JIRA installation or a public domain).
Example:
<script type="text/javascript" src="http://YOUR_JIRA_SERVER/includes/custom/javascript/custom.js"></script>
If you add it like above, go into your JIRA installation into the atlassian-jira/includes/ folder and add a folder called custom within which you add another folder called javascript and create a file called custom.js.
In that file, add the following code:
AJS.$(document).ready(function()
{
AJS.$(document.body).on('change', '#issuetype-field', function()
{
var issuetype = AJS.$(this).val();
if(issuetype === "Test") //Might want to change this!
{
AJS.$("#fixVersions").val(17403); //Might want to change this!
}
});
});
This will add an eventlistener to the issuetype-field input found in the create modal window in JIRA. When it changes (which it automatically does on load, then on every user select) it check its value to see if it's Test and if so changes the fixVersion input to a whatever you want to set it to (change this to match your own preferences).
Using jQuery with jira is a bit tricky, you need to use the AJS object to access the jQuery object (more information here: https://docs.atlassian.com/aui/latest/docs/applicationHeader.html).
The two parts you need to change are the actual names and values of your issuetype and your fix version (use firebug or your browsers equivalent to get this).
I've tried this and it worked well! Good luck!
I have two questions regarding Fortify.
1 - Lets say I have a windows forms app, which asks for a username
and password, and the name of the textbox for password is
texboxPassword. So in the designer file, you have the following,
generated by the designer.
//
// texboxPassword
//
this.texboxPassword.Location = new System.Drawing.Point(16, 163);
this.texboxPassword.Name = "texboxPassword";
this.texboxPassword.Size = new System.Drawing.Size(200, 73);
this.texboxPassword.TabIndex = 3;
Fortify marks this as a password in comment issue. How can I suppress this by creating a custom rule? I don't want to suppress the whole issue because I still would like to catch certain patterns (such as password followed by = or : in comments) but the blanket search where any line that contains password is flagged is creating so many false positives. I looked into creating a structural rule but could not figure out how to remove the associated tag (where can I find the tag for password in comment anyways?)
2 - Let's say I have a custom UI control. This control html encodes everything and in my context, it is good enough to avoid XSS. Needless to say, it is being flagged by Fortify. How can I suppress XSS when I have a certain control type in my UI and all of its methods are safe for XSS (they sanitize) in my context? I have tried a DataflowCleanseRule (with a label just to test the concept) and wanted to mark get_Text() and set_Text() as sanitizer functions, but it did not make a difference and Fortify still flagged it for XSS.
<DataflowCleanseRule formatVersion="3.16" language="dotnet">
<RuleID>0D495522-BA81-440E-B191-48A67D9092BE</RuleID>
<TaintFlags>+VALIDATED_CROSS_SITE_SCRIPTING_REFLECTED,+VALIDATED_CROSS_SITE_SCRIPTING_PERSISTENT,+VALIDATED_CROSS_SITE_SCRIPTING_DOM,+VALIDATED_CROSS_SITE_SCRIPTING_POOR_VALIDATION</TaintFlags>
<FunctionIdentifier>
<NamespaceName>
<Pattern>System.Web.UI.WebControls</Pattern>
</NamespaceName>
<ClassName>
<Pattern>Label</Pattern>
</ClassName>
<FunctionName>
<Pattern>_Text</Pattern>
</FunctionName>
<ApplyTo implements="true" overrides="true" extends="true"/>
</FunctionIdentifier>
<OutArguments>return</OutArguments>
</DataflowCleanseRule>
Thank you in advance for your help
This is parsed using regular expressions. Unless you think you are able to create a regular expression that can parse human language properly, I would leave it alone and just audit it as not an issue.
The Pattern tag uses a java regular expression in the body, so should be used as user2867433 suggested. However, you stated
This control html encodes everything and in my context, it is good enough to avoid XSS
If you are going to use a custom rule, this has to assume that it will work in EVERY context, as say in the future somebody writes a piece of code that uses get_Text and then places this directly into a piece of JavaScript, html encoding will do NOTHING to stop the XSS problem here. I would advise again to audit this as not an issue or a false positive due to the validation used and explain why it's good enough in that context
Within "Pattern" you can use Java-Regex. So it should work if you use [gs]et_Text
I'm currently running a fairly out-of-the-box JIRA setup that is live and being used.
Now I'm at a point where I would like a custom field in each bug that will display the total amount of times and issue/bug has been reopened.
There is a plugin (https://answers.atlassian.com/questions/19665/how-to-count-based-on-status-jira) that does something similar, however, I am looking for a solution that doesn't require purchasing a third-party plugin (OPS doesn't like plugins).
I've searched forums high and low and was unable to even find a good starting point. Your help is always appreciated. Thanks in advance!
EDIT: Current JIRA version: 5.2
Create a custom field for counting the times an issue was opened, and set it's default value to one. Then use the Behaviours Plugin to add validation script to the transitions you wish to count. In the validation script, increment the custom field and return true. should be something like:
FormField formComponent = getFieldById(fieldChanged)
FormField formUserField = getFieldByName("UserFieldA"
formUserField.setFormValue(Integer.valueOf(formUserField.getFormValue()) + 1)
If you're having trouble coding that have a look here or ask here.
An easier way would be to attack a post-function to the re-open transition using
Jira Scripting Suite and use it to increment the field, but it doesn't support Jira 5.2 yet.
If you don't want to use any plugins, you can use Webhooks attached to the re-open workflow transition that will post to an URL , which in turn, will connect back using the REST API and increment that field.
A Custom field holds some information (metric, counter, misc. info, etc.) but it is not logic by itself. So the problem here is that in order to increment a (custom) field you will have to have some logic doing that. So you're left with three options:
Use the plugin you're talking about
Custom-build a plugin for this
Use a custom-built external application utilizing the REST API that polls for changes on issues and when it detects "Reopenings" and increments the custom field's value.
Manually assign this field (not really an option)
So at the end there aren't that many options that do not require resouces - development or purchasing some plugin. Usually it's best to buy a plugin because you're also buying support with that. However beware that if the plugin is not developed by Atlassian there is the possibility that it may not support future JIRA versions or it may not be compatible right after a new JIRA version release.
My solution is to add the post-function to the 'Reopen' transition with the following code (it assumes you have Script Runner plugin installed and enabled; also you have to add custom field 'Reopen count' to the corresponding view screen):
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
def componentManager = ComponentManager.getInstance()
def customFieldManager = componentManager.getCustomFieldManager()
def reopenCount = customFieldManager.getCustomFieldObjects(issue).find {it.name == 'Reopen count'}
def changeHolder = new DefaultIssueChangeHolder();
def reopenCountValue = issue.getCustomFieldValue(reopenCount)
if(reopenCountValue == null) reopenCountValue = 0.0d
reopenCount.updateValue(
null,
issue,
new ModifiedValue(
reopenCountValue,
++reopenCountValue
),
changeHolder
);
Tagsoup is interfering with input and formatting it incorrectly. For instance when we have the following markup
Text outside anchor
It is formatted as follows
Text outside anchor
This is a simple example but we have other issues as well. So we made tagsoup cleanup/formatting optional by adding an extra attribute to textarea control.
Here is the diff(https://github.com/binnyg/orbeon-forms/commit/044c29e32ce36e5b391abfc782ee44f0354bddd3).
Textarea would now look like this
<textarea skip-cleanmarkup="true" mediatype="text/html" />
Two questions
Is this the right approach?
If I provide a patch can it make it to orbeon codebase?
Thanks
BinnyG
Erik, Alex, et al
I think there are two questions here:
The first Concern is a question of Tag Soup and the clean up that happens OOTB: Empty tags are converted to singleton tags which when consumed/sent to the client browser as markup gets "fixed" by browsers like firefox but because of the loss of precision they do the wrong thing.
Turning off this clean up helps in this case but for this issue alone is not really the right answer because we it takes away a security feature and a well-formed markup feature... so there may need to be some adjustment to the handling of at least certain empty tags (other than turning them in to invalid singleton tags.)
All this brings us to the second concern which is do we always want those features in play? Our use-case says no. We want the user to be able to spit out whatever markup they want, invalid or not. We're not putting the form in an app that needs to protect the user from cross script coding, we're building a tool that lets users edit web pages -- hence we have turned off the clean-up.
But turning off cleanup wholesale? Well it's important that we can do it if that's what our usecase calls for but the implementation we have is all or nothing. It would be nice to be able to define strategies for cleanup. Make that function plug-able. For example:
* In the XML Config of the system define a "map" of config names to class names which implement the a given strategy. In the XForm Def the author would specify the name from the map.
If TagSoup transforms:
Text outside anchor
Into:
Text outside anchor
Wouldn't that be bug in TagSoup? If that was the case, then I'd say that it is better to fix this issue rather than disable TagSoup. But, it isn't a bug in TagSoup; here is what seems to be happening. Say the browsers sends the following to the client:
<a shape="rect"></a>After<br clear="none">
This goes through TagSoup, the result goes through the XSLT clean-up code, and the following is sent to the browser:
<a shape="rect"/>After<br clear="none"/>
The issue is on the browser, which transforms this into:
<a shape="rect">After</a><br clear="none"/>
The problem is that we serialize this as XML with Dom4jUtils.domToString(cleanedDocument), while it would be more prudent to serialize it as HTML. Here we could use the Saxon serializer. It is also used from HTMLSerializer. Maybe you can try changing this code to use it instead of using Dom4jUtils.domToString(). You'll let us know what you find when a get a chance to do that.
Binesh and I agree, if there is a bug it would be a good idea to address the issue closer to the root. But I think the specific issue he is only part of the matter.
We're thinking it would be best to have some kind of name-to-strategy mapping so that RTEs can call in the server-side processing that is right for them or the default if it's not specified.