[5e44432] | 1 | from ..attribute import Attribute |
---|
| 2 | from ..attributegroup import AttributeGroup |
---|
| 3 | from ..request import Request |
---|
| 4 | from ..value import Value |
---|
| 5 | from .. import errors |
---|
| 6 | from .. import constants as consts |
---|
| 7 | |
---|
| 8 | def verify_operations(request): |
---|
| 9 | """Pretty much all requests have the first attribute group for |
---|
| 10 | operation attributes, and these all have 'attributes-charset' and |
---|
| 11 | 'attributes-natural-language' as the first two attributes. This |
---|
| 12 | method just generically verifies that these attributes are there. |
---|
| 13 | |
---|
| 14 | """ |
---|
| 15 | |
---|
| 16 | # XXX: check version |
---|
| 17 | if False: |
---|
| 18 | raise errors.VersionNotSupported(str(request.version)) |
---|
| 19 | |
---|
| 20 | # XXX: check operation id |
---|
| 21 | if False: |
---|
| 22 | raise errors.OperationNotSupported(str(request.operation_id)) |
---|
| 23 | |
---|
| 24 | # check operation attributes tag |
---|
| 25 | op_attrs = request.attribute_groups[0] |
---|
| 26 | if op_attrs.tag != consts.AttributeTags.OPERATION: |
---|
| 27 | raise errors.BadRequest( |
---|
| 28 | "Attribute group does not have OPERATION tag: 0x%x" % op_attrs.tag) |
---|
| 29 | |
---|
| 30 | # XXX: if these aren't valid, then you HAVE to return something |
---|
| 31 | # special. See RFC 2911 3.1.6.1 |
---|
| 32 | # # check compression |
---|
| 33 | # if False: |
---|
| 34 | # raise errors.CompressionNotSupported |
---|
| 35 | |
---|
| 36 | # # check document format |
---|
| 37 | # if False: |
---|
| 38 | # raise errors.DocumentFormatNotSupported |
---|
| 39 | |
---|
| 40 | # # check document uri |
---|
| 41 | # if False: |
---|
| 42 | # raise errors.UriSchemeNotSupported |
---|
| 43 | |
---|
| 44 | # check charset |
---|
| 45 | charset_attr = op_attrs.attributes[0] |
---|
| 46 | if charset_attr.name != 'attributes-charset': |
---|
| 47 | raise errors.BadRequest( |
---|
| 48 | "Attribute is not attributes-charset: %s" % charset_attr.name) |
---|
| 49 | if len(charset_attr.values) != 1: |
---|
| 50 | raise errors.BadRequest( |
---|
| 51 | "Too many values for attributes-charset: %d" % len(charset_attr.values)) |
---|
| 52 | # check charset value |
---|
| 53 | charset_value = charset_attr.values[0] |
---|
| 54 | if charset_value.tag != consts.operations_attribute_value_tags['attributes-charset']: |
---|
| 55 | raise errors.BadRequest( |
---|
| 56 | "Wrong tag for charset value: 0x%x" % charset_value.tag) |
---|
| 57 | if charset_value.value != 'utf-8': |
---|
| 58 | raise errors.CharsetNotSupported(str(charset_value.value)) |
---|
| 59 | |
---|
| 60 | # check for attributes-natural-language |
---|
| 61 | natlang_attr = op_attrs.attributes[1] |
---|
| 62 | if natlang_attr.name != 'attributes-natural-language': |
---|
| 63 | raise errors.BadRequest( |
---|
| 64 | "Attribute is not attributes-natural-language: %s" % natlang_attr.name) |
---|
| 65 | if len(charset_attr.values) != 1: |
---|
| 66 | raise errors.BadRequest( |
---|
| 67 | "Too many values for attributes-natural-language: %s" % len(natlang_attr.values)) |
---|
| 68 | # check natural language value |
---|
| 69 | natlang_value = natlang_attr.values[0] |
---|
| 70 | if natlang_value.tag != consts.operations_attribute_value_tags['attributes-natural-language']: |
---|
| 71 | raise errors.BadRequest( |
---|
| 72 | "Natural language value does not have NATURAL_LANGUAGE tag: 0x%x" % natlang_value.tag) |
---|
| 73 | if natlang_value.value != 'en-us': |
---|
| 74 | raise errors.Attributes( |
---|
| 75 | "Invalid natural language value: %s" % natlang_value.value, [natlang_attr]) |
---|
| 76 | |
---|
| 77 | return dict([(attr.name, attr.values) for attr in op_attrs.attributes]) |
---|
| 78 | |
---|
| 79 | def verify_printer_uri(values): |
---|
| 80 | if len(values) != 1: |
---|
| 81 | raise errors.BadRequest( |
---|
| 82 | "Requesting printer uri attribute has too many values: %d" % len(values)) |
---|
| 83 | uri_value = values[0] |
---|
| 84 | if uri_value.tag != consts.operations_attribute_value_tags['printer-uri']: |
---|
| 85 | raise errors.BadRequest( |
---|
| 86 | "Bad value tag (expected URI): 0x%x" % uri_value_tag) |
---|
| 87 | |
---|
| 88 | # actually get the printer name |
---|
| 89 | # XXX: hack -- CUPS will strip the port from the request, so |
---|
| 90 | # we can't do an exact comparison (also the hostname might be |
---|
| 91 | # different, depending on the CNAME or whether it's localhost) |
---|
| 92 | uri = uri_value.value.split("/")[-1] |
---|
| 93 | return uri |
---|
| 94 | |
---|
| 95 | def verify_requesting_username(values): |
---|
| 96 | if len(values) != 1: |
---|
| 97 | raise errors.BadRequest( |
---|
| 98 | "Requesting user name attribute has too many values: %d" % len(values)) |
---|
| 99 | requser_value = values[0] |
---|
| 100 | if requser_value.tag != consts.operations_attribute_value_tags['requesting-user-name']: |
---|
| 101 | raise errors.BadRequest( |
---|
| 102 | "Bad value tag (expected NAME_WITHOUT_LANGUAGE): 0x%x" % requser_value.tag) |
---|
| 103 | |
---|
| 104 | return requser_value.value |
---|
| 105 | |
---|
| 106 | def make_empty_response(request): |
---|
| 107 | # Operation attributes -- typically the same for any request |
---|
| 108 | attributes = [ |
---|
| 109 | Attribute( |
---|
| 110 | 'attributes-charset', |
---|
| 111 | [Value(consts.operations_attribute_value_tags['attributes-charset'], 'utf-8')]), |
---|
| 112 | Attribute( |
---|
| 113 | 'attributes-natural-language', |
---|
| 114 | [Value(consts.operations_attribute_value_tags['attributes-natural-language'], |
---|
| 115 | 'en-us')]) |
---|
| 116 | ] |
---|
| 117 | # Put the operation attributes in a group |
---|
| 118 | attribute_group = AttributeGroup( |
---|
| 119 | consts.AttributeTags.OPERATION, |
---|
| 120 | attributes) |
---|
| 121 | |
---|
| 122 | # Set up the default response -- handlers will override these |
---|
| 123 | # values if they need to |
---|
| 124 | response_kwargs = {} |
---|
| 125 | response_kwargs['version'] = request.version |
---|
| 126 | response_kwargs['operation_id'] = consts.StatusCodes.OK |
---|
| 127 | response_kwargs['request_id'] = request.request_id |
---|
| 128 | response_kwargs['attribute_groups'] = [attribute_group] |
---|
| 129 | response = Request(**response_kwargs) |
---|
| 130 | |
---|
| 131 | return response |
---|
| 132 | |
---|
| 133 | def make_job_attributes(attrs, request, response): |
---|
| 134 | ipp_attrs = [] |
---|
| 135 | for attr, vals in attrs: |
---|
| 136 | ipp_vals = [Value( |
---|
| 137 | tag=consts.job_attribute_value_tags[attr], |
---|
| 138 | value=val) for val in vals] |
---|
| 139 | ipp_attrs.append(Attribute(name=attr, values=ipp_vals)) |
---|
| 140 | response.attribute_groups.append(AttributeGroup( |
---|
| 141 | consts.AttributeTags.JOB, ipp_attrs)) |
---|
| 142 | |
---|
| 143 | def make_printer_attributes(attrs, request, response): |
---|
| 144 | ipp_attrs = [] |
---|
| 145 | for attr, vals in attrs: |
---|
| 146 | ipp_vals = [Value( |
---|
| 147 | tag=consts.printer_attribute_value_tags[attr], |
---|
| 148 | value=val) for val in vals] |
---|
| 149 | ipp_attrs.append(Attribute(name=attr, values=ipp_vals)) |
---|
| 150 | response.attribute_groups.append(AttributeGroup( |
---|
| 151 | consts.AttributeTags.PRINTER, ipp_attrs)) |
---|
| 152 | |
---|
| 153 | |
---|
| 154 | from cups_get_classes import verify_cups_get_classes_request, make_cups_get_classes_response |
---|
| 155 | from cups_get_default import verify_cups_get_default_request, make_cups_get_default_response |
---|
| 156 | from cups_get_printers import verify_cups_get_printers_request, make_cups_get_printers_response |
---|
| 157 | |
---|
| 158 | from get_jobs import verify_get_jobs_request, make_get_jobs_response |
---|
| 159 | from get_printer_attributes import verify_get_printer_attributes_request |
---|
| 160 | from get_printer_attributes import make_get_printer_attributes_response |
---|
| 161 | |
---|
| 162 | __all__ = ['verify_cups_get_classes_request', |
---|
| 163 | 'make_cups_get_classes_response', |
---|
| 164 | 'verify_cups_get_default_request', |
---|
| 165 | 'make_cups_get_default_response', |
---|
| 166 | 'verify_cups_get_printers_request', |
---|
| 167 | 'make_cups_get_printers_response', |
---|
| 168 | 'verify_get_jobs_request', |
---|
| 169 | 'make_get_jobs_response', |
---|
| 170 | 'verify_get_printer_attributes_request', |
---|
| 171 | 'make_get_printer_attributes_response', |
---|
| 172 | |
---|
| 173 | 'verify_operations', |
---|
| 174 | 'verify_printer_uri', |
---|
| 175 | 'verify_requesting_username', |
---|
| 176 | |
---|
| 177 | 'make_empty_response', |
---|
| 178 | 'make_job_attributes', |
---|
| 179 | 'make_printer_attributes'] |
---|