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'] |
---|