def auth(request, api, version, format, product_code): ''' Overview: Attempt an authentication for a product using supplied credentials. If successful, a session key is obtained that can be used for requests to protected resources/content. The base URL scheme for this entry point is: /:api/:version/:format/auth/:productcode In this particular case, the api is "paywallproxy" and the version is v1.0.0. Currently, the only supported format is "json". The URL for this entry point therefore looks like: /paywallproxy/v1.0.0/json/auth/:productcode If the product cannot be found, an "InvalidProduct" error should be returned. This error will be returned to the client. A full list of errors that this entry point returns is available below. Client errors are proxied to the client. Server errors remain on Polar's server. An auth-scheme token is expected when a call is made to this API end point. It must conform to RFC 2617 specifications. The authorization header has the following form: Authorization: PolarPaywallProxyAuthv1.0.0 Parameters: There are two sets of parameters that this API entry point requires. The first set consists of the product code, which is specified in the URL and the post body, which contains formatted json. Technical details will follow after a description of the parameters and an example will follow after that. The product code is part of the URL. It is a publisher-assigned unique identifier for this product. The product code is required. The post body is a json map with two keys. The first key is "device", which is a json map describing the device requesting authorization. This key is required. The second key is "authParams", which is optional. The "device" map contains three keys. "manufacturer" is the full name of the device manufacturer. "model" is the device's model number and name. "os_version" is a string that describes the version of the device's operating system. The contents of the "authParams" map will vary based on the settings on the Polar server. The keys of the map is the name of the parameter set on the server. The values of the map is the value entered by the user. Details regarding the various parameters are described below. Product Code: A publisher-assigned unique identifier for this product. Availability: >= v1.0.0 Required: Yes Location: URL Format: URL Type: String Max Length: 256 device: A json map describing the device requesting authorization. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: json map Max Length: N/A manufacturer: The full name of the device manufacturer. Contained in the "device" map. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 256 model: The device's model number and name. Contained in the "device" map. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 256 os_version: The version of the device's operating system. Contained in the "device" map. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 256 authParams: A map of the authentication parameters and their values. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: map Max Length: N/A authParams key: The name of the authentication parameter. Contained in the "authParams" map. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 256 authParams value: The user entered value of the authentication parameter. Contained in the "authParams" map. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 512 Response: The following parameters are returned by this API end point. The resposne is json encoded. It has two keys; "sessionKey" and "products". "sessionKey" is a key that allows the client to re-authenticate without the supplied authentication parameters. "products" is a list of product identifiers that the user has access to. sessionKey: A key that allows the client to re-authenticate without the supplied authentication parameters. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 512 products: A list of product identifiers that the user has access to. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: list Max Length: N/A product: A publisher-assigned unique identifier for this product that the user has access to. Contained in the "products" list. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 256 Example: Example Request: POST /paywallproxy/v1.0.0/json/auth/gold-level HTTP/1.1 Authorization: PolarPaywallAuthv1.0.0 123:x Content-Type: application/json { "device": { "manufacturer": "Phake Phones Inc.", "model": "90", "os_version": "1.1.1" }, "authParams": { "username": "******", "password": "******" } } Example Response: HTTP/1.1 200 OK Content-Type: application/json { "sessionKey": "9c4a51cc08d1879570c", "products": [ "gold-level", "silver-level" ] } Errors: Some of the following errors are marked optional. They are included in this example for completeness and testing purposes. Implementing them makes testing the connection between Polar's server and the publishers server easier. InvalidPaywallCredentials: Thrown when the authentication parameters are invalid. Code: InvalidPaywallCredentials Message: Varies with the error. HTTP Error Code: 401 Required: Yes AccountProblem: There is a problem with the user's account. The user is prompted to contact technical support. Code: AccountProblem Message: Your account is not valid. Please contact support. HTTP Error Code: 403 Required: Yes InvalidProduct: Thrown when the product code indicated is invalid. Code: InvalidProduct Message: The requested article could not be found. HTTP Error Code: 404 Required: Yes InvalidAPI: Returned when the publisher does not recognize the requested api. Code: InvalidAPI Message: An error occurred. Please contact support. Debug: The requested api is not implemented: <api> HTTP Error Code: 404 Required: No InvalidVersion: Returned when the publisher does not recognize the requested version. Code: InvalidVersion Message: An error occurred. Please contact support. Debug: The requested version is not implemented: <version> HTTP Error Code: 404 Required: No InvalidFormat: Returned when the publisher does not recognize the requested format. Code: InvalidFormat Message: An error occurred. Please contact support. Debug: The requested format is not implemented: <format> HTTP Error Code: 404 Required: No InvalidDevice: Returned when the request does not specify the device parameters properly. Code: InvalidDevice Message: An error occurred. Please contact support. Debug: Varies with the error. HTTP Error Code: 400 Required: No InvalidAuthParams: Returned when the request does not specify the authParams parameter properly. Code: InvalidAuthParams Message: An error occurred. Please contact support. Debug: Varies with the error. HTTP Error Code: 400 Required: No InvalidAuthScheme: Returned when the publisher does not recognize the requested format. Code: InvalidAuthScheme Message: An error occurred. Please contact support. Debug: Varies with the error. HTTP Error Code: 400. Required: No ''' # Store the full URL string so that it can be used to report errors. url = request.path # Validate the request and its headers. check_base_url(url, api, version, format) check_authorization_header(url, request._environ) # Validate the request body. body = decode_body(url, request.body) check_device(url, body) check_auth_params(url, body) # Note that the authentication parameters that will be passed into this # service are configurable through Polar's server. The function # check_publisher_auth_params ensures that the authentication parameters # specific to this publisher's implementation (username, password) exist # and are strings. check_publisher_auth_params(url, body) username = body['authParams']['username'] password = body['authParams']['password'] # Authenticate the user to get the session id and the products. (session_id, products) = model().authenticate_user(url, username, password, product_code) # Create the response body. result = {} result['sessionKey'] = session_id result['products'] = products content = dumps(result) status = 200 headers = [] content_type = 'application/json' return Response(content, headers, status, content_type)
def validate(request, api, version, format, product_code): ''' Overview: Attempt an authorization for a product using supplied session key (transmitted via the Authorization header). This API call is used periodically to validate that the session is still valid and the user should continue to be allowed to access protected resources. If the call returns a 401, a new authentication call must be made. The base URL scheme for this entry point is: /:api/:version/:format/validate/:productcode In this particular case, the api is "paywallproxy" and the version is v1.0.0. Currently, the only supported format is "json". The URL for this entry point therefore looks like: /paywallproxy/v1.0.0/json/validate/:productcode If the product cannot be found, an "InvalidProduct" error should be returned. This error will be returned to the client. A full list of errors that this entry point returns is available below. Client errors are proxied to the client. Server errors remain on Polar's server. Parameters: There are two sets of parameters that this API entry point requires. The first set consists of the product code, which is specified in the URL and the session id, which is specified in the authorization header. The product code is part of the URL. It is a publisher-assigned unique identifier for this product. The product code is required. An auth-scheme token is expected when a call is made to this API end point. It must conform to RFC 2617 specifications. The authorization header has the following form: Authorization: PolarPaywallProxySessionv1.0.0 session:<session id> Note that the session id is passed as a parameter through the authorization token. Details regarding the various parameters are described below. Product Code: A publisher-assigned unique identifier for this product. Availability: >= v1.0.0 Required: Yes Location: URL Format: URL Type: String Max Length: 256 Session Id: A session id generated by calling the auth entry point of this API. Availability: >= v1.0.0 Required: Yes Location: Header Format: Header Type: String Max Length: 512 Response: The following parameters are returned by this API end point. The resposne is json encoded. It has two keys; "sessionKey" and "products". "sessionKey" is a key that allows the client to re-authenticate without the supplied authentication parameters. "products" is a list of product identifiers that the user has access to. sessionKey: A key that allows the client to re-authenticate without the supplied authentication parameters. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 512 products: A list of product identifiers that the user has access to. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: list Max Length: N/A product: A publisher-assigned unique identifier for this product that the user has access to. Contained in the "products" list. Availability: >= v1.0.0 Required: Yes Location: POST Body Format: json Type: string Max Length: 256 Example: Example Request: POST /validate/gold-level HTTP/1.1 Authorization: PolarPaywallProxySessionv1.0.0 session:9c4a51cc08d1 Example Response: HTTP/1.1 200 OK Content-Type: application/json { "sessionKey": "9c4a51cc08d1", "products": [ "gold-level", "silver-level" ] } Errors: Some of the following errors are marked optional. They are included in this example for completeness and testing purposes. Implementing them makes testing the connection between Polar's server and the publishers server easier. AccountProblem: There is a problem with the user's account. The user is prompted to contact technical support. Code: InvalidPaywallCredentials Message: Your account is not valid. Please contact support. HTTP Error Code: 403 Required: Yes InvalidProduct: Thrown when the product code indicated is invalid. Code: InvalidProduct Message: The requested article could not be found. HTTP Error Code: 404 Required: Yes SessionExpired: The session key provided has expired. Re-authenticate (to obtain a new session key) and retry the request. Code: SessionExpired Message: The session key provided has expired. HTTP Error Code: 401 Required: Yes InvalidAPI: Returned when the publisher does not recognize the requested api. Code: InvalidAPI Message: An error occurred. Please contact support. Debug: The requested api is not implemented: <api> HTTP Error Code: 404 Required: No InvalidVersion: Returned when the publisher does not recognize the requested version. Code: InvalidVersion Message: An error occurred. Please contact support. Debug: The requested version is not implemented: <version> HTTP Error Code: 404 Required: No InvalidFormat: Returned when the publisher does not recognize the requested format. Code: InvalidFormat Message: An error occurred. Please contact support. Debug: The requested format is not implemented: <format> HTTP Error Code: 404 Required: No InvalidAuthScheme: Returned when the publisher does not recognize the requested format. Code: InvalidAuthScheme Message: An error occurred. Please contact support. Message: Varies with the error. HTTP Error Code: 400. Required: No ''' # Store the full URL string so that it can be used to report errors. url = request.path # Validate the request. check_base_url(url, api, version, format) if len(request.body.strip()) > 0: # If there is a body for this API call, that implies that the caller # is not conforming to the API, so raise an error. code = 'InvalidFormat' message = 'Invalid post body.' status = 400 raise_error(url, code, message, status) # Validate the session id using the data model. session_id = get_session_id(url, request._environ) products = model().validate_session(url, session_id, product_code) # Create the response body. result = {} result['sessionKey'] = session_id result['products'] = products content = dumps(result) status = 200 headers = [] content_type = 'application/json' return Response(content, headers, status, content_type)