Skip to content

Commit d689906

Browse files
committed
Merge branch 'release/2.0.6'
2 parents a01f4fb + 0258788 commit d689906

File tree

12 files changed

+230
-22
lines changed

12 files changed

+230
-22
lines changed

.docker/Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
FROM splitbrain/phpfarm:jessie
1+
FROM php:7.4-apache
22

3-
RUN apt-get update && apt-get install -y git zip
3+
RUN apt-get update \
4+
&& apt-get install -y libxml2-dev git zip \
5+
&& docker-php-ext-install soap
46

57
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
68
COPY . /var/www/

.github/CODE_OF_CONDUCT.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6+
7+
## Our Standards
8+
9+
Examples of behavior that contributes to creating a positive environment include:
10+
11+
* Using welcoming and inclusive language
12+
* Being respectful of differing viewpoints and experiences
13+
* Gracefully accepting constructive criticism
14+
* Focusing on what is best for the community
15+
* Showing empathy towards other community members
16+
17+
Examples of unacceptable behavior by participants include:
18+
19+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
20+
* Trolling, insulting/derogatory comments, and personal or political attacks
21+
* Public or private harassment
22+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
23+
* Other conduct which could reasonably be considered inappropriate in a professional setting
24+
25+
## Our Responsibilities
26+
27+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28+
29+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30+
31+
## Scope
32+
33+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34+
35+
## Enforcement
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [email protected]. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38+
39+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40+
41+
## Attribution
42+
43+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44+
45+
[homepage]: http://contributor-covenant.org
46+
[version]: http://contributor-covenant.org/version/1/4/

.github/CONTRIBUTING.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Contributing
2+
3+
Contributions are **welcome** and will be fully **credited**.
4+
5+
We accept contributions via pull requests on [Github].
6+
Please make all pull requests to the `develop` branch, not the `master` branch.
7+
8+
## Before posting an issue
9+
10+
- If a command is failing, post the full output you get when running the command, with the `--verbose` argument
11+
12+
## Pull Requests
13+
14+
- **Create an issue** - Explain as detailed as possible the issue you encountered so we can understand the context of your pull request
15+
- **[Symfony Coding Standard]** - The easiest way to apply the conventions is to run `composer lint`
16+
- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
17+
- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
18+
- **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
19+
- **Create feature branches** - Don't ask us to pull from your master branch.
20+
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
21+
- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
22+
23+
## Running Tests
24+
25+
``` bash
26+
$ composer test
27+
```
28+
29+
**Happy coding**!
30+
31+
[Github]: https://github.com/wsdltophp/wssecurity
32+
[Symfony Coding Standard]: http://symfony.com/doc/current/contributing/code/standards.html

.github/workflows/sonarcloud.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: SonarCloud
2+
on:
3+
push:
4+
branches:
5+
- develop
6+
- feature/*
7+
- feat/*
8+
pull_request:
9+
types: [ opened, synchronize, reopened ]
10+
jobs:
11+
sonarcloud:
12+
name: SonarCloud
13+
runs-on: ubuntu-latest
14+
permissions:
15+
pull-requests: write
16+
steps:
17+
- uses: actions/checkout@v2
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Setup PHP with Xdebug
22+
uses: shivammathur/setup-php@v2
23+
with:
24+
php-version: 7.4
25+
coverage: xdebug
26+
27+
- name: Install dependencies with composer
28+
run: composer update --no-ansi --no-interaction --no-progress
29+
30+
- name: Generate coverage report with phpunit/phpunit
31+
run: vendor/bin/phpunit --coverage-clover coverage.xml --log-junit report.xml
32+
33+
- name: Monitor coverage
34+
if: false
35+
uses: slavcodev/coverage-monitor-action@v1
36+
with:
37+
github_token: ${{ secrets.SECRET_GITHUB_TOKEN }}
38+
coverage_path: coverage.xml
39+
threshold_alert: 75
40+
threshold_warning: 95
41+
42+
- name: Codecov analyze
43+
uses: codecov/codecov-action@v3
44+
with:
45+
files: coverage.xml
46+
47+
- name: Fix phpunit files paths
48+
run: sed -i 's@'$GITHUB_WORKSPACE/'@''@g' coverage.xml report.xml
49+
50+
- name: SonarCloud Scan
51+
uses: SonarSource/sonarcloud-github-action@master
52+
env:
53+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CHANGELOG
22

3+
## 2.0.6 - 2024/09/04
4+
- PR #20, issue #19 - Attributes on Timestamp
5+
36
## 2.0.5 - 2022/05/05
47
- Merged PR #15
58

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,22 @@ The `WsSecurity::createWsSecuritySoapHeader` parameters are defined in this orde
4444
- **$mustunderstand**: classic option of the [\SoapClient](http://php.net/manual/en/soapclient.soapclient.php) class
4545
- **$actor**: classic option of the [\SoapClient](http://php.net/manual/en/soapclient.soapclient.php) class
4646
- **$usernameId**: the id to attach to the UsernameToken element, optional
47-
- **$addNonce**: _true_ by default, if true, it adds the nonce element to the header, if false it does not add the nonce element to the header
47+
- **$addNonce**: _true_ by default, if true, it adds the nonce element to the header, if false it does not add the nonce element to the header
48+
49+
## Alternative usage ##
50+
Create an instance of the Security class
51+
```php
52+
use WsdlToPhp\WsSecurity\WsSecurity;
53+
54+
$wsSecurity = new WsSecurity('login', 'password', true, /*$addCreated*/ time());
55+
56+
// access its properties to alter them
57+
$wsSecurity->getSecurity()->getTimestamp()->setAttribute('wsu:Id', 'AnyRequestValue');
58+
59+
// Get the SoapHeader
60+
$header = $security->getSoapHeader($returnSoapHeader = true, $mustunderstand = false, $actor = null);
61+
```
62+
4863

4964
## Testing using [Docker](https://www.docker.com/)
5065
Thanks to the [Docker image](https://hub.docker.com/r/splitbrain/phpfarm) of [phpfarm](https://github.com/fpoirotte/phpfarm), tests can be run locally under *any* PHP version using the cli:
@@ -58,9 +73,9 @@ $ docker-compose up -d --build
5873
You then have a container named `ws_security` in which you can run `composer` commands and `php cli` commands such as:
5974
```bash
6075
# install deps in container (using update ensure it does use the composer.lock file if there is any)
61-
$ docker exec -it ws_security php-7.4 /usr/bin/composer update
76+
$ docker exec -it ws_security php /usr/bin/composer update
6277
# run tests in container
63-
$ docker exec -it ws_security php-7.4 -dmemory_limit=-1 vendor/bin/phpunit
78+
$ docker exec -it ws_security php -dmemory_limit=-1 vendor/bin/phpunit
6479
```
6580

6681
## FAQ

phpunit.xml.dist

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="vendor/autoload.php">
33
<coverage>
44
<include>
5-
<directory>./</directory>
5+
<directory>./src</directory>
66
</include>
7-
<exclude>
8-
<directory>./src/resources</directory>
9-
<directory>./tests</directory>
10-
<directory>./vendor</directory>
11-
</exclude>
127
</coverage>
138
<testsuites>
149
<testsuite name="full">

sonar-project.properties

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
sonar.projectKey=WsdlToPhp_WsSecurity
2+
sonar.organization=wsdltophp
3+
sonar.php.coverage.reportPaths=coverage.xml
4+
sonar.php.tests.reportPath=report.xml
5+
6+
sonar.sources=src/
7+
sonar.tests=tests/

src/Password.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function __construct(string $password, string $typeValue = self::TYPE_PAS
2020
{
2121
$this
2222
->setTypeValue($typeValue)
23-
->setTimestampValue($timestampValue ? $timestampValue : time())
23+
->setTimestampValue($timestampValue ?: time())
2424
->setNonceValue((string) mt_rand())
2525
;
2626

src/Timestamp.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ class Timestamp extends Element
1010
{
1111
public const NAME = 'Timestamp';
1212

13-
protected ?Created $created;
13+
protected ?Created $created = null;
1414

15-
protected ?Expires $expires;
15+
protected ?Expires $expires = null;
1616

1717
public function __construct(string $namespace = self::NS_WSU)
1818
{

src/WsSecurity.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class WsSecurity
1111
{
1212
protected Security $security;
1313

14-
protected function __construct(
14+
public function __construct(
1515
string $username,
1616
string $password,
1717
bool $passwordDigest = false,
@@ -55,15 +55,21 @@ public static function createWsSecuritySoapHeader(
5555
string $envelopeNamespace = Security::ENV_NAMESPACE
5656
) {
5757
$self = new WsSecurity($username, $password, $passwordDigest, $addCreated, $addExpires, $mustUnderstand, $actor, $usernameId, $addNonce, $envelopeNamespace);
58+
59+
return $self->getSoapHeader($returnSoapHeader, $mustUnderstand, $actor);
60+
}
61+
62+
public function getSoapHeader(bool $returnSoapHeader = true, bool $mustUnderstand = false, ?string $actor = null): object
63+
{
5864
if ($returnSoapHeader) {
5965
if (!empty($actor)) {
60-
return new SoapHeader(Element::NS_WSSE, Security::NAME, new SoapVar($self->getSecurity()->toSend(), XSD_ANYXML), $mustUnderstand, $actor);
66+
return new SoapHeader(Element::NS_WSSE, Security::NAME, new SoapVar($this->getSecurity()->toSend(), XSD_ANYXML), $mustUnderstand, $actor);
6167
}
6268

63-
return new SoapHeader(Element::NS_WSSE, Security::NAME, new SoapVar($self->getSecurity()->toSend(), XSD_ANYXML), $mustUnderstand);
69+
return new SoapHeader(Element::NS_WSSE, Security::NAME, new SoapVar($this->getSecurity()->toSend(), XSD_ANYXML), $mustUnderstand);
6470
}
6571

66-
return new SoapVar($self->getSecurity()->toSend(), XSD_ANYXML);
72+
return new SoapVar($this->getSecurity()->toSend(), XSD_ANYXML);
6773
}
6874

6975
protected function initSecurity(bool $mustUnderstand = false, ?string $actor = null, string $envelopeNamespace = Security::ENV_NAMESPACE): self
@@ -115,12 +121,18 @@ protected function setCreated(int $addCreated): self
115121
protected function setTimestamp(int $addCreated = 0, int $addExpires = 0): self
116122
{
117123
$timestampValue = $this->getPassword()->getTimestampValue();
118-
if ($addCreated && $addExpires && $timestampValue) {
119-
$timestamp = new Timestamp();
124+
if (!$timestampValue || (0 === $addCreated && 0 === $addExpires)) {
125+
return $this;
126+
}
127+
128+
$timestamp = new Timestamp();
129+
if (0 < $addCreated) {
120130
$timestamp->setCreated(new Created($timestampValue));
131+
}
132+
if (0 < $addExpires) {
121133
$timestamp->setExpires(new Expires($timestampValue, $addExpires));
122-
$this->security->setTimestamp($timestamp);
123134
}
135+
$this->security->setTimestamp($timestamp);
124136

125137
return $this;
126138
}

tests/WsSecurityTest.php

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
/**
1111
* @internal
12-
* @coversDefaultClass
12+
* @coversDefaultClass \WsdlToPhp\WsSecurity\WsSecurity
1313
*/
1414
final class WsSecurityTest extends TestCase
1515
{
@@ -44,6 +44,9 @@ public function testCreateWithoutExpiresIn()
4444
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
4545
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
4646
</wsse:UsernameToken>
47+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
48+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
49+
</wsu:Timestamp>
4750
</wsse:Security>'), $header->data->enc_value);
4851
}
4952

@@ -59,6 +62,9 @@ public function testCreateWithMustUnderstand()
5962
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
6063
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
6164
</wsse:UsernameToken>
65+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
66+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
67+
</wsu:Timestamp>
6268
</wsse:Security>'), $header->data->enc_value);
6369
}
6470

@@ -74,6 +80,9 @@ public function testCreateWithMustUnderstandAndActor()
7480
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
7581
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
7682
</wsse:UsernameToken>
83+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
84+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
85+
</wsu:Timestamp>
7786
</wsse:Security>'), $header->data->enc_value);
7887
}
7988

@@ -89,6 +98,9 @@ public function testCreateSoapVar()
8998
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
9099
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
91100
</wsse:UsernameToken>
101+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
102+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
103+
</wsu:Timestamp>
92104
</wsse:Security>'), $header->enc_value);
93105
}
94106

@@ -104,6 +116,9 @@ public function testCreateWithPasswordDigest()
104116
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
105117
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
106118
</wsse:UsernameToken>
119+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
120+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
121+
</wsu:Timestamp>
107122
</wsse:Security>'), $header->enc_value);
108123
}
109124

@@ -119,6 +134,9 @@ public function testCreateWithUsernameId()
119134
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
120135
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
121136
</wsse:UsernameToken>
137+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
138+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
139+
</wsu:Timestamp>
122140
</wsse:Security>'), $header->data->enc_value);
123141
}
124142

@@ -133,6 +151,28 @@ public function testCreateWithoutNonce()
133151
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password>
134152
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
135153
</wsse:UsernameToken>
154+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
155+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
156+
</wsu:Timestamp>
157+
</wsse:Security>'), $header->data->enc_value);
158+
}
159+
160+
public function testWithTimestampAttribute()
161+
{
162+
$security = new WsSecurity('foo', 'bar', false, 1459451824, 0, false, null, null, false);
163+
$security->getSecurity()->getTimestamp()->setAttribute('wsu:Id', 'Timestamp-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX');
164+
$header = $security->getSoapHeader();
165+
$this->assertInstanceOf(SoapHeader::class, $header);
166+
$this->assertMatches(self::innerTrim('
167+
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
168+
<wsse:UsernameToken>
169+
<wsse:Username>foo</wsse:Username>
170+
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password>
171+
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
172+
</wsse:UsernameToken>
173+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX">
174+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
175+
</wsu:Timestamp>
136176
</wsse:Security>'), $header->data->enc_value);
137177
}
138178

@@ -161,6 +201,9 @@ public function testCreateWithEnvelopeNamespace()
161201
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-03-31T19:17:04Z</wsu:Created>
162202
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">([a-zA-Z0-9=]*)</wsse:Nonce>
163203
</wsse:UsernameToken>
204+
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
205+
<wsu:Created>2016-03-31T19:17:04Z</wsu:Created>
206+
</wsu:Timestamp>
164207
</wsse:Security>'), $header->data->enc_value);
165208
}
166209
}

0 commit comments

Comments
 (0)