Skip to content

Commit

Permalink
Merge branch 'FreeOpcUa:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Ilyazyk authored Jun 20, 2024
2 parents 28f483a + ec112a8 commit 8027648
Show file tree
Hide file tree
Showing 36 changed files with 204 additions and 158 deletions.
10 changes: 5 additions & 5 deletions asyncua/common/connection.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
import hashlib
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
import logging
import copy

Expand Down Expand Up @@ -256,7 +256,7 @@ def open(self, params, server):
self.security_token.TokenId = 13 # random value
self.security_token.ChannelId = server.get_new_channel_id()
self.security_token.RevisedLifetime = params.RequestedLifetime
self.security_token.CreatedAt = datetime.utcnow()
self.security_token.CreatedAt = datetime.now(timezone.utc)

response.SecurityToken = self.security_token

Expand All @@ -270,7 +270,7 @@ def open(self, params, server):
self.next_security_token = copy.deepcopy(self.security_token)
self.next_security_token.TokenId += 1
self.next_security_token.RevisedLifetime = params.RequestedLifetime
self.next_security_token.CreatedAt = datetime.utcnow()
self.next_security_token.CreatedAt = datetime.now(timezone.utc)

response.SecurityToken = self.next_security_token

Expand Down Expand Up @@ -358,8 +358,8 @@ def _check_sym_header(self, security_hdr):
# network delays.
timeout = self.prev_security_token.CreatedAt + \
timedelta(milliseconds=self.prev_security_token.RevisedLifetime * 1.25)
if timeout < datetime.utcnow():
raise ua.UaError(f"Security token id {security_hdr.TokenId} has timed out " f"({timeout} < {datetime.utcnow()})")
if timeout < datetime.now(timezone.utc):
raise ua.UaError(f"Security token id {security_hdr.TokenId} has timed out " f"({timeout} < {datetime.now(timezone.utc)})")
return

expected_tokens = [self.security_token.TokenId, self.next_security_token.TokenId]
Expand Down
6 changes: 3 additions & 3 deletions asyncua/common/statemachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __init__(self, id, name: str = None, number: int = None, node: Node = None):
self.id = id # in this case it needs to be added with add_transition which takes the nodeid returen from add_transition
self.name = name
self.number = number
self._transitiontime = datetime.datetime.utcnow() # will be overwritten from _write_transition()
self._transitiontime = datetime.datetime.now(datetime.timezone.utc) # will be overwritten from _write_transition()
self.node: Node = node # will be written from statemachine.add_state() or you need to overwrite it if the state is part of xml


Expand Down Expand Up @@ -131,7 +131,7 @@ async def install(self, optionals: bool = False):
self._last_transition_transitiontime_node = await self._last_transition_node.add_property(
0,
"TransitionTime",
ua.Variant(datetime.datetime.utcnow(), VariantType=ua.VariantType.DateTime)
ua.Variant(datetime.datetime.now(datetime.timezone.utc), VariantType=ua.VariantType.DateTime)
)
else:
self._last_transition_transitiontime_node = await self._last_transition_node.get_child("TransitionTime")
Expand Down Expand Up @@ -218,7 +218,7 @@ async def _write_transition(self, transition: Transition):
'''
if not isinstance(transition, Transition):
raise ValueError(f"Statemachine: {self._name} -> state: {transition} is not a instance of StateMachine.Transition class")
transition._transitiontime = datetime.datetime.utcnow()
transition._transitiontime = datetime.datetime.now(datetime.timezone.utc)
await self._last_transition_node.write_value(ua.LocalizedText(transition.name, self.locale), ua.VariantType.LocalizedText)
if self._optionals:
if self._last_transition_id_node:
Expand Down
5 changes: 3 additions & 2 deletions asyncua/common/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import uuid
import logging
# The next two imports are for generated code
from datetime import datetime
from datetime import datetime, timezone
from enum import IntEnum, EnumMeta
from dataclasses import dataclass, field
from typing import List, Optional
Expand Down Expand Up @@ -217,7 +217,7 @@ def _make_header(self, _file):
THIS FILE IS AUTOGENERATED, DO NOT EDIT!!!
'''
from datetime import datetime
from datetime import datetime, timezone
import uuid
from dataclasses import dataclass, field
from typing import List, Union
Expand Down Expand Up @@ -300,6 +300,7 @@ def _generate_python_class(model, env=None):
env['ua'] = ua
if "datetime" not in env:
env['datetime'] = datetime
env['timezone'] = timezone
if "uuid" not in env:
env['uuid'] = uuid
if "enum" not in env:
Expand Down
5 changes: 3 additions & 2 deletions asyncua/common/structures104.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from enum import Enum
from enum import IntEnum, IntFlag
from datetime import datetime
from datetime import datetime, timezone
import uuid
import logging
import re
Expand Down Expand Up @@ -154,7 +154,7 @@ def get_default_value(uatype, enums=None, hack=False, optional=False):
if uatype == "Boolean":
return "True"
if uatype == "DateTime":
return "datetime.utcnow() # type: ignore"
return "datetime.now(timezone.utc) # type: ignore"
if uatype in ("Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "Double", "Float", "Byte", "SByte"):
return f"ua.{uatype}(0)"
if uatype in enums:
Expand Down Expand Up @@ -277,6 +277,7 @@ async def _generate_object(name, sdef, data_type=None, env=None, enum=False, opt
env['ua'] = ua
if "datetime" not in env:
env['datetime'] = datetime
env['timezone'] = timezone
if "uuid" not in env:
env['uuid'] = uuid
if "enum" not in env:
Expand Down
6 changes: 3 additions & 3 deletions asyncua/common/ua_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import uuid
import logging
from datetime import datetime
from datetime import datetime, timezone
from enum import Enum, IntEnum, IntFlag

from dateutil import parser # type: ignore[attr-defined]
Expand All @@ -21,8 +21,8 @@ def value_to_datavalue(val, varianttype=None):
if isinstance(val, ua.DataValue):
return val
if isinstance(val, ua.Variant):
return ua.DataValue(val, SourceTimestamp=datetime.utcnow())
return ua.DataValue(ua.Variant(val, varianttype), SourceTimestamp=datetime.utcnow())
return ua.DataValue(val, SourceTimestamp=datetime.now(timezone.utc))
return ua.DataValue(ua.Variant(val, varianttype), SourceTimestamp=datetime.now(timezone.utc))


def val_to_string(val, truncate=False):
Expand Down
8 changes: 4 additions & 4 deletions asyncua/crypto/cert_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ def generate_self_signed_app_certificate(private_key: rsa.RSAPrivateKey,
builder = x509.CertificateBuilder()
builder = builder.subject_name(x509.Name(name_attributes))
builder = builder.issuer_name(x509.Name(name_attributes))
builder = builder.not_valid_before(datetime.datetime.utcnow())
builder = builder.not_valid_after(datetime.datetime.utcnow() + (ONE_DAY * days))
builder = builder.not_valid_before(datetime.datetime.now(datetime.timezone.utc))
builder = builder.not_valid_after(datetime.datetime.now(datetime.timezone.utc) + (ONE_DAY * days))
builder = builder.serial_number(serial_number)
builder = builder.public_key(public_key)
builder = builder.add_extension(
Expand Down Expand Up @@ -212,8 +212,8 @@ def sign_certificate_request(csr: x509.CertificateSigningRequest,
builder = x509.CertificateBuilder()
builder = builder.subject_name(csr.subject)
builder = builder.issuer_name(issuer.subject)
builder = builder.not_valid_before(datetime.datetime.utcnow())
builder = builder.not_valid_after(datetime.datetime.utcnow() + (ONE_DAY * days))
builder = builder.not_valid_before(datetime.datetime.now(datetime.timezone.utc))
builder = builder.not_valid_after(datetime.datetime.now(datetime.timezone.utc) + (ONE_DAY * days))
builder = builder.serial_number(serial_number)
builder = builder.public_key(public_key)
builder = builder.add_extension(
Expand Down
14 changes: 7 additions & 7 deletions asyncua/crypto/truststore.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from typing import List
from pathlib import Path
import re
from datetime import datetime
from datetime import datetime, timezone
import logging
from cryptography import x509
from OpenSSL import crypto
Expand Down Expand Up @@ -80,7 +80,7 @@ def validate(self, certificate: x509.Certificate) -> bool:
return self.is_trusted(certificate) and self.is_revoked(certificate) is False and self.check_date_range(certificate)

def check_date_range(self, certificate: x509.Certificate) -> bool:
""" Checks if the certificate not_valid_before and not_valid_after are valid.
""" Checks if the certificate not_valid_before_utc and not_valid_after_utc are valid.
Args:
certificate (x509.Certificate): Certificate to check
Expand All @@ -89,12 +89,12 @@ def check_date_range(self, certificate: x509.Certificate) -> bool:
bool: Returns True when the now lays in valid range of the certificate
"""
valid: bool = True
now = datetime.utcnow()
if certificate.not_valid_after < now:
_logger.error('certificate is no longer valid: valid until %s', certificate.not_valid_after)
now = datetime.now(timezone.utc)
if certificate.not_valid_after_utc < now:
_logger.error('certificate is no longer valid: valid until %s', certificate.not_valid_after_utc)
valid = False
if certificate.not_valid_before > now:
_logger.error('certificate is not yet vaild: valid after %s', certificate.not_valid_before)
if certificate.not_valid_before_utc > now:
_logger.error('certificate is not yet vaild: valid after %s', certificate.not_valid_before_utc)
valid = False
return valid

Expand Down
2 changes: 1 addition & 1 deletion asyncua/crypto/uacrypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def x509_to_string(cert):
else:
issuer = f', issuer: {x509_name_to_string(cert.issuer)}'
# TODO: show more information
return f"{x509_name_to_string(cert.subject)}{issuer}, {cert.not_valid_before} - {cert.not_valid_after}"
return f"{x509_name_to_string(cert.subject)}{issuer}, {cert.not_valid_before_utc} - {cert.not_valid_after_utc}"


def check_certificate(cert: x509.Certificate, application_uri: str, hostname: Optional[str] = None) -> bool:
Expand Down
8 changes: 4 additions & 4 deletions asyncua/crypto/validator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Callable, Awaitable, Optional
import logging
from datetime import datetime
from datetime import datetime, timezone
from enum import Flag, auto
from cryptography import x509
from cryptography.x509.oid import ExtendedKeyUsageOID
Expand Down Expand Up @@ -78,10 +78,10 @@ async def validate(self, cert: x509.Certificate, app_description: ua.Application
"""

if CertificateValidatorOptions.TIME_RANGE in self._options:
now = datetime.utcnow()
if cert.not_valid_after < now:
now = datetime.now(timezone.utc)
if cert.not_valid_after_utc < now:
raise ServiceError(ua.StatusCodes.BadCertificateTimeInvalid)
elif cert.not_valid_before > now:
elif cert.not_valid_before_utc > now:
raise ServiceError(ua.StatusCodes.BadCertificateTimeInvalid)
try:
san = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
Expand Down
8 changes: 4 additions & 4 deletions asyncua/server/address_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pickle
import shelve
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from datetime import datetime, timezone
from functools import partial
from pathlib import Path
from typing import TYPE_CHECKING, Optional
Expand Down Expand Up @@ -103,7 +103,7 @@ async def write(self, params: ua.WriteParameters, user: User = User(role=UserRol
res.append(ua.StatusCode(ua.StatusCodes.BadUserAccessDenied))
continue
if writevalue.AttributeId == ua.AttributeIds.Value and self._aspace.force_server_timestamp:
dv = dataclasses.replace(writevalue.Value, ServerTimestamp=datetime.utcnow(), ServerPicoseconds=None)
dv = dataclasses.replace(writevalue.Value, ServerTimestamp=datetime.now(timezone.utc), ServerPicoseconds=None)
else:
dv = writevalue.Value
res.append(
Expand Down Expand Up @@ -512,8 +512,8 @@ def _add_node_attr(
if attributes.SpecifiedAttributes & getattr(ua.NodeAttributesMask, name):
dv = ua.DataValue(
ua.Variant(getattr(attributes, name), vtype, is_array=is_array),
SourceTimestamp=datetime.utcnow() if add_timestamps else None,
ServerTimestamp=datetime.utcnow() if add_timestamps and self._aspace.force_server_timestamp else None,
SourceTimestamp=datetime.now(timezone.utc) if add_timestamps else None,
ServerTimestamp=datetime.now(timezone.utc) if add_timestamps and self._aspace.force_server_timestamp else None,
)
nodedata.attributes[getattr(ua.AttributeIds, name)] = AttributeValue(dv)

Expand Down
6 changes: 3 additions & 3 deletions asyncua/server/event_generator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from datetime import datetime
from datetime import datetime, timezone
import time
import uuid
import sys
Expand Down Expand Up @@ -86,8 +86,8 @@ async def trigger(self, time_attr=None, message=None, subscription_id=None):
if time_attr:
self.event.Time = time_attr
else:
self.event.Time = datetime.utcnow()
self.event.ReceiveTime = datetime.utcnow()
self.event.Time = datetime.now(timezone.utc)
self.event.ReceiveTime = datetime.now(timezone.utc)

self.event.LocalTime = ua.uaprotocol_auto.TimeZoneDataType()
if sys.version_info.major > 2:
Expand Down
7 changes: 4 additions & 3 deletions asyncua/server/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import asyncio
import logging
from datetime import timedelta
from datetime import datetime
from datetime import timedelta
from datetime import timezone

from asyncua import ua
from asyncua.common import subscription
Expand Down Expand Up @@ -114,7 +115,7 @@ async def save_node_value(self, node_id, datavalue):
data = self._datachanges[node_id]
period, count = self._datachanges_period[node_id]
data.append(datavalue)
now = datetime.utcnow()
now = datetime.now(timezone.utc)
if period:
while len(data) and now - data[0].SourceTimestamp > period:
data.pop(0)
Expand Down Expand Up @@ -172,7 +173,7 @@ async def save_event(self, event):
evts = self._events[event.emitting_node]
evts.append(event)
period, count = self._events_periods[event.emitting_node]
now = datetime.utcnow()
now = datetime.now(timezone.utc)
if period:
while len(evts) and now - evts[0].Time > period:
evts.pop(0)
Expand Down
8 changes: 4 additions & 4 deletions asyncua/server/history_sql.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import sqlite3
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Iterable

import aiosqlite
Expand Down Expand Up @@ -89,7 +89,7 @@ async def save_node_value(self, node_id, datavalue):
period, count = self._datachanges_period[node_id]
if period:
# after the insert, if a period was specified delete all records older than period
date_limit = datetime.utcnow() - period
date_limit = datetime.now(timezone.utc) - period
validate_table_name(table)
await self.execute_sql_delete("SourceTimestamp < ?", (date_limit,), table, node_id)
if count:
Expand Down Expand Up @@ -175,7 +175,7 @@ async def save_event(self, event):
period = self._datachanges_period[event.emitting_node]
if period:
# after the insert, if a period was specified delete all records older than period
date_limit = datetime.utcnow() - period
date_limit = datetime.now(timezone.utc) - period
try:
validate_table_name(table)
await self._db.execute(f'DELETE FROM "{table}" WHERE Time < ?', (date_limit.isoformat(' '),))
Expand Down Expand Up @@ -241,7 +241,7 @@ def _get_bounds(start, end, nb_values):
order = "DESC"
start = ua.get_win_epoch()
if end is None or end == ua.get_win_epoch():
end = datetime.utcnow() + timedelta(days=1)
end = datetime.now(timezone.utc) + timedelta(days=1)
if start < end:
start_time = start.isoformat(" ")
end_time = end.isoformat(" ")
Expand Down
8 changes: 4 additions & 4 deletions asyncua/server/internal_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""
from typing import Callable, Optional
import asyncio
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from copy import copy
from struct import unpack_from
from pathlib import Path
Expand Down Expand Up @@ -129,7 +129,7 @@ async def setup_nodes(self):
attr.Value = ua.DataValue(
ua.Variant(10000, ua.VariantType.UInt32),
StatusCode_=ua.StatusCode(ua.StatusCodes.Good),
SourceTimestamp=datetime.utcnow(),
SourceTimestamp=datetime.now(timezone.utc),
)
params.NodesToWrite.append(attr)
result = await self.isession.write(params)
Expand Down Expand Up @@ -194,7 +194,7 @@ async def start(self):
await Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_State)).write_value(
ua.ServerState.Running, ua.VariantType.Int32
)
await Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).write_value(datetime.utcnow())
await Node(self.isession, ua.NodeId(ua.ObjectIds.Server_ServerStatus_StartTime)).write_value(datetime.now(timezone.utc))
if not self.disabled_clock:
self.time_task = asyncio.create_task(self._set_current_time_loop())

Expand All @@ -209,7 +209,7 @@ async def stop(self):

async def _set_current_time_loop(self):
while not self._time_task_stop:
await self.current_time_node.write_value(datetime.utcnow())
await self.current_time_node.write_value(datetime.now(timezone.utc))
await asyncio.sleep(1)

def get_new_channel_id(self):
Expand Down
Loading

0 comments on commit 8027648

Please sign in to comment.