Passed
Push — develop ( f534b1...a82689 )
by Plexxi
06:09 queued 03:13
created

CorsMiddleware.__call__()   C

Complexity

Conditions 8

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
c 1
b 0
f 0
dl 0
loc 52
rs 5.5452

1 Method

Rating   Name   Duplication   Size   Complexity  
B CorsMiddleware.custom_start_response() 0 41 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
from oslo_config import cfg
17
from webob.headers import ResponseHeaders
18
19
from st2common.constants.api import REQUEST_ID_HEADER
20
from st2common.constants.auth import HEADER_ATTRIBUTE_NAME
21
from st2common.constants.auth import HEADER_API_KEY_ATTRIBUTE_NAME
22
from st2common.router import Request, Response, NotFoundException
23
24
25
class CorsMiddleware(object):
26
    def __init__(self, app):
27
        self.app = app
28
29
    def __call__(self, environ, start_response):
30
        request = Request(environ)
31
32
        def custom_start_response(status, headers, exc_info=None):
33
            headers = ResponseHeaders(headers)
34
35
            origin = request.headers.get('Origin')
36
            origins = set(cfg.CONF.api.allow_origin)
37
38
            # Build a list of the default allowed origins
39
            public_api_url = cfg.CONF.auth.api_url
40
41
            # Default gulp development server WebUI URL
42
            origins.add('http://127.0.0.1:3000')
43
44
            # By default WebUI simple http server listens on 8080
45
            origins.add('http://localhost:8080')
46
            origins.add('http://127.0.0.1:8080')
47
48
            if public_api_url:
49
                # Public API URL
50
                origins.add(public_api_url)
51
52
            if origin:
53
                if '*' in origins:
54
                    origin_allowed = '*'
55
                else:
56
                    # See http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
57
                    origin_allowed = origin if origin in origins else 'null'
58
            else:
59
                origin_allowed = list(origins)[0]
60
61
            methods_allowed = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
62
            request_headers_allowed = ['Content-Type', 'Authorization', HEADER_ATTRIBUTE_NAME,
63
                                       HEADER_API_KEY_ATTRIBUTE_NAME, REQUEST_ID_HEADER]
64
            response_headers_allowed = ['Content-Type', 'X-Limit', 'X-Total-Count',
65
                                        REQUEST_ID_HEADER]
66
67
            headers['Access-Control-Allow-Origin'] = origin_allowed
68
            headers['Access-Control-Allow-Methods'] = ','.join(methods_allowed)
69
            headers['Access-Control-Allow-Headers'] = ','.join(request_headers_allowed)
70
            headers['Access-Control-Expose-Headers'] = ','.join(response_headers_allowed)
71
72
            return start_response(status, headers._items, exc_info)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _items was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
73
74
        try:
75
            return self.app(environ, custom_start_response)
76
        except NotFoundException:
77
            if request.method != 'options':
78
                raise
79
80
            return Response()(environ, custom_start_response)
0 ignored issues
show
Bug introduced by
Response() does not seem to be callable.
Loading history...
81