<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    I just read the code did not testing, maybe I will read design
    tomorrow.<br>
    <br>
    I found a few minor issues<br>
    <br>
    0)<br>
    You use too much brackets in code, it looks more like C than python:<br>
    if not(elem):  --> if not elem<br>
    if(len(elempair) > 2) --> if len(elempair) > 2:<br>
    return(something) --> return something<br>
    <br>
    1)<br>
    +def _timearg_to_list(time):<br>
    +    '''<br>
    +    Parses the argument of either of the access time language
    keywords<br>
    +<br>
    +    Example: '1-5,12' into [[1,5], 12]<br>
    +    '''<br>
    +    return (t.split('-') for t in time.split(','))<br>
    <br>
    This will return [['1', '5'], ['12']] please fix example<br>
    <br>
    2)<br>
    in function _validate_range(keyword, lst, r1, r2, unit, unitlen): I
    do not like that enumeration and this condition<br>
    +            if not(i):<br>
    +                elold = elnum<br>
    <br>
    Can you use instead enumeration just None?<br>
    elold = None<br>
    if elold is None:<br>
        elold = elnum<br>
    <br>
    3)<br>
    _validate_timeofday(t)<br>
    I do not like that enumerate (see 2) )<br>
    <br>
    4)<br>
    _validate_timeofday(t)<br>
    There is missing check for values like '1-2-5', '1-2,', (this check
    is in _validate_range)<br>
    <br>
    5)<br>
    I do not think that unitlen arg in _validate_range is needed, IMO
    this is duplicated check, comparison r1, r2 is enough<br>
    <br>
    6)<br>
    +def validate_accesstime(ugettext, value):<br>
    This function is not pythonic enough, it looks more like C<br>
    <br>
    I suggest something like:<br>
    <br>
    params = { name: {'found': False, 'method': method } for name,
    method in [<br>
        ('dayofweek', _validate_dayofweek),<br>
        ('timeofday', _validate_timeof...),<br>
    .....<br>
    ]}<br>
    <br>
    for i, el enumerate(ts):<br>
        param_name, param_value = el.split('=', 1)<br>
        try:<br>
            res = params[param_name]['method'](param_value) if not
    params[param_name]['found'] else _("multiple blablabla of
    {param}".format(param=param_name))<br>
            params[param_name]['found'] = True<br>
        except KeyError:<br>
            res = _(Unknown.....)<br>
        if res:<br>
           return res<br>
    <br>
    7)<br>
    +            res = _validate_timeofday(el[10:]) if not(found[TOD])
    else \<br>
    +                _("multiple appearance of timeofday")<br>
    <br>
    Please don't use '\', use braces instead<br>
    <br>
    <br>
    8)<br>
    -        'externalhost',<br>
    +        'memberhostgroup', 'externalhost', 'ipatimezone',<br>
    +        'accesstime', 'accesstimeexclude'<br>
    <br>
    Are you sure that 'memberhostgroup' should be added there? I don't
    think so.<br>
    <br>
    9)<br>
    def normalize_accesstime(t):<br>
    IIRC normalize is called before validate, so your precious regular
    expression may not work as expected, namely:<br>
    +    t = re.sub(r'(\d)([a-z]{2})', r'\1 \2', t)<br>
    +    t = re.sub(r'(\d)\s(d|w|m|y)\s', r'\1\2', t)<br>
    However when normalization returns unexpected results, validation
    will be able catch it.<br>
    <br>
    IMO we should not do any magic detection, we should force user to
    have keyword and value pairs separated by space<br>
    <br>
    How about depending on '=' character in normalization?<br>
    parts = re.split('[\s=]', t)<br>
    eq_signs_pos = [i for i, part in enumeration(parts) if parts=="="]<br>
    <here join it based on = sign, something like<br>
    parts:<br>
    [year, '=', 'i', 'do', 'not', 'care', 'next', '=', 'lorem', 'ipsum']<br>
    eq_signs_pos:<br>
    [1, 7]<br>
    keyword_pos:<br>
    [0,6]<br>
    Test if keyword is on position 0: else raise conversionerror<br>
    normalized = " ".join(["".join([parts[0], .. parts[5]]),
    "".join([parts[6]..parts[9]])])<br>
    <br>
    result "year=idonotcare next=loremipsum"<br>
    ><br>
    <br>
    10)<br>
    _validate_date()<br>
<a class="moz-txt-link-freetext" href="http://stackoverflow.com/questions/16870663/how-do-i-validate-a-date-string-format-in-python">http://stackoverflow.com/questions/16870663/how-do-i-validate-a-date-string-format-in-python</a><br>
    <br>
    I know the solution above is not so detailed in what is wrong, but
    IMO to print that specified date is not valid should be enough for
    user.<br>
    <br>
    11)<br>
    in _validate_date function I see validation for case when dayofmonth
    is higher than, last day of month. I do not see this check for other
    cases than 'repeat'. Is it safe to ignore (for example:
    "dayofmonth=30 monthofyear=2" this HBACrule will never be executed)?<br>
    <br>
    12)<br>
    +    if not('1' <= t[ctlpos] <= '9'):<br>
    +        return _("'repeat': wrong syntax, expected a number after
    '+'")<br>
    <br>
    IMO 0 is digit/number too, and we should allow initial 0 and just
    ignore them during execution<br>
    <br>
    13)<br>
    +def _validate_repeat(t):<br>
    +    date1 = t[0:8]<br>
    <br>
    what if 't' is shorter than 8 characters?<br>
    <br>
    14)<br>
    +    date2 = t[9:17] if t[8] == '-' else None        <br>
    What if t < 17 characters and t[8] == '-'?<br>
    <br>
    15)<br>
    +    if t[ctlpos] not in ('d', 'w', 'm', 'y'):<br>
    +        return _("'repeat': wrong syntax, d/w/m/y expected")<br>
    <br>
    What if there is any continuation after?
    "repeat=20151003+2m-trolololo" (you can add this to tests :) )<br>
        <br>
    16)<br>
    IMO _validate_repeat check looks simple enough to be checked by
    regexp, and then separate parts tested extra (start, end date,
    repeat period)<br>
    <br>
    17)<br>
    +def _validate_ymd_range(y1, m1, d1, y2, m2, d2):<br>
    <br>
    Can you instead of this black magic use python datetime object?
    <a class="moz-txt-link-freetext" href="https://docs.python.org/2/library/datetime.html">https://docs.python.org/2/library/datetime.html</a><br>
    And then just compare 2 objects with '>' and return error that
    second date is greater than first.<br>
    <br>
    Also datetime object creation will check if date itself.<br>
    <br>
    18)<br>
    +    rule_time = u'timeofday=0000-2359 dayofmonth=1-15,16-31 ' \<br>
    +                 'dayofyear=23-47,26-77 year=1970-2563'<br>
    Please use () instead of \<br>
    <br>
    19)<br>
    +    # no spaces around - sign   <-- ~ should be there<br>
    +    t = re.sub(r'\s?~\s?', r'~', t)<br>
    <br>
    wouldn't be better to work with ~ since first patch? I mean replace
    '-' -> '~' in first patch<br>
    <br>
    Is common to specify date ranges with '~' ? Personally I wouldn't
    expected that.<br>
    <br>
    20)<br>
    Please add design page to the ticket (if exists)
    <a class="moz-txt-link-freetext" href="https://fedorahosted.org/freeipa/ticket/547">https://fedorahosted.org/freeipa/ticket/547</a><br>
    <br>
    21)<br>
    PEP8<br>
    <br>
    ./ipalib/plugins/hbacrule.py:190:21: E265 block comment should start
    with '# '<br>
    ./ipatests/test_xmlrpc/test_hbac_plugin.py:38:18: E127 continuation
    line over-indented for visual indent<br>
    ./ipatests/test_xmlrpc/test_hbac_plugin.py:38:18: E127 continuation
    line over-indented for visual indent<br>
    ./ipatests/test_xmlrpc/test_hbac_plugin.py:101:80: E501 line too
    long (84 > 79 characters)<br>
    ./ipalib/plugins/hbactest.py:281:9: E124 closing bracket does not
    match visual indentation<br>
    ./ipalib/plugins/hbacrule.py:78:80: E501 line too long (80 > 79
    characters)<br>
    ./ipalib/plugins/hbacrule.py:190:21: E265 block comment should start
    with '# '<br>
    ./ipalib/plugins/hbacrule.py:219:80: E501 line too long (84 > 79
    characters)<br>
    ./ipalib/plugins/hbacrule.py:592:9: E124 closing bracket does not
    match visual indentation<br>
    ./ipalib/plugins/hbacrule.py:596:9: E124 closing bracket does not
    match visual indentation<br>
    <br>
    22)<br>
    Unwanted lines removal at the end of files/patches<br>
    * Added methods for setting time-based policies: hbacrule.py<br>
    * HBAC test module support for time-based policies: hbactest.py<br>
    * Tests for HBAC time rules language: test_hbactest_plugin.py<br>
    <br>
    best regards<br>
    Martin^2<br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 07.10.2015 09:55, Stanislav Laznicka
      wrote:<br>
    </div>
    <blockquote cite="mid:5614CFE1.7030705@redhat.com" type="cite">Hi,
      <br>
      <br>
      The moment's here, I'd like to share my code with you now. Let me
      comment on some additions from my last post here in August.
      <br>
      <br>
      The methods for testing HBAC rules in hbactest module were
      modified so that a time zone can now also be picked in case there
      are some rules with the "host" time zone in the rule time policy.
      I also added few tests that test setting accessTime values.
      <br>
      <br>
      The most important update of the previous month is the addition of
      negative values to the time rules language. Most of the keywords
      (all, except for timeofday and year) now accept negative values
      and negative value ranges. This should be useful for cases when
      the user should only be allowed access e.g. in the last 7 days of
      a month, last few weeks of a year etc. Also, it is a similar
      behavior to what iCalendar has.
      <br>
      <br>
      The addition of negative values also made me re-think the ways the
      week of a year should be calculated. There are no 0th weeks of
      year anymore, a week of year can hold values ranging from 1 to 53
      where the 1st week of a year may appear even on a date of the
      previous year (if 1st January is Tue-Thu) or the 52nd or 53rd week
      may appear on a date of the following year (when 31st December is
      Thu-Sat). If my explanation seems rather rough, please see
<a class="moz-txt-link-freetext" href="https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html">https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html</a>.<br>
      <br>
      The latter caused some changes to be made in my SSSD code. These
      changes took the most of my time last month alongside with
      generally polishing the code and adding comments where I thought
      necessary. I will push my SSSD code to the sssd-devel mailing list
      as a follow-up to this mail.
      <br>
      <br>
      Another thing - I updated the design page on the FreeIPA wiki, so
      please check it out, too
      (<a class="moz-txt-link-freetext" href="http://www.freeipa.org/page/V4/Time-Based_Account_Policies">http://www.freeipa.org/page/V4/Time-Based_Account_Policies</a>).
      <br>
      <br>
      Last thing I would like to mention - there is now a copr repo with
      both sssd and freeipa with time-based policies
      (<a class="moz-txt-link-freetext" href="https://copr.fedoraproject.org/coprs/stlaz/freeipa-sssd-timerules/">https://copr.fedoraproject.org/coprs/stlaz/freeipa-sssd-timerules/</a>).
      This was Martin K.'s idea and I think it's pretty dandy :) As the
      patches I am posting only contain CLI for HBAC time policies, you
      might be pleased that the repo includes at least basic WebUI for
      this purpose (although the WebUI is for some reason not updating
      the page on rule addition properly, I will be hopefully looking
      into that shortly). You will still need mkosek/freeipa-master copr
      repo for some dependencies. Should it not work properly for you,
      please, send me an email, it's my first time taking care of a copr
      repo.
      <br>
      <br>
      That's it from me for now, thank you for your patience with my
      emails,
      <br>
      Standa
      <br>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
    </blockquote>
    <br>
  </body>
</html>