text:
@interface AFRefreshControlNotificationObserver : NSObject
@property (readonly, nonatomic, weak) UIRefreshControl *refreshControl;
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl;

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
#endif
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation;

@end

@implementation UIRefreshControl (AFNetworking)

- (AFRefreshControlNotificationObserver *)af_notificationObserver {
    AFRefreshControlNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver));
    if (notificationObserver == nil) {
        notificationObserver = [[AFRefreshControlNotificationObserver alloc] initWithActivityRefreshControl:self];
        objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return notificationObserver;
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
    [[self af_notificationObserver] setRefreshingWithStateOfTask:task];
}
#endif

- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation {
    [[self af_notificationObserver] setRefreshingWithStateOfOperation:operation];
}

@end

@implementation AFRefreshControlNotificationObserver

- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl
{
    self = [super init];
    if (self) {
        _refreshControl = refreshControl;
    }
    return self;
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

    [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];

    if (task) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
        if (task.state == NSURLSessionTaskStateRunning) {
            [self.refreshControl beginRefreshing];

            [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task];
        } else {
            [self.refreshControl endRefreshing];
        }
#pragma clang diagnostic pop
    }
}
#endif

- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

    [notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];

    if (operation) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
        if (![operation isFinished]) {
            if ([operation isExecuting]) {
                [self.refreshControl beginRefreshing];
            } else {
                [self.refreshControl endRefreshing];
            }

            [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingOperationDidStartNotification object:operation];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingOperationDidFinishNotification object:operation];
        }
#pragma clang diagnostic pop
    }
}

#pragma mark -

- (void)af_beginRefreshing {
    dispatch_async(dispatch_get_main_queue(), ^{
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Wreceiver-is-weak"
        [self.refreshControl beginRefreshing];
//#pragma clang diagnostic pop
    });
}

- (void)af_endRefreshing {
    dispatch_async(dispatch_get_main_queue(), ^{
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Wreceiver-is-weak"
        [self.refreshControl endRefreshing];
//#pragma clang diagnostic pop
    });
}

#pragma mark -

- (void)dealloc {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
#endif

    [notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
}

@end

#endif


text:
[![CI Status](https://github.com/zmartzone/lua-resty-openidc/actions/workflows/docker-ci.yml/badge.svg)](https://github.com/zmartzone/lua-resty-openidc/actions/workflows/docker-ci.yml)
[<img width="184" height="96" align="right" src="http://openid.net/wordpress-content/uploads/2016/04/oid-l-certification-mark-l-rgb-150dpi-90mm@2x.png" alt="OpenID Certification">](https://openid.net/certification)

# lua-resty-openidc

**lua-resty-openidc** is a library for [NGINX](http://nginx.org/) implementing the
[OpenID Connect](http://openid.net/specs/openid-connect-core-1_0.html) **Relying Party (RP)**
and/or the [OAuth 2.0](https://tools.ietf.org/html/rfc6749) **Resource Server (RS)** functionality.

When used as an OpenID Connect Relying Party it authenticates users against an OpenID Connect
Provider using [OpenID Connect Discovery](http://openid.net/specs/openid-connect-discovery-1_0.html)
and the Basic Client Profile (i.e. the Authorization Code flow). When used as an OAuth 2.0
Resource Server it can validate OAuth 2.0 Bearer Access Tokens against an Authorization Server or, in
case a JSON Web Token is used for an Access Token, verification can happen against a pre-configured secret/key .

It maintains sessions for authenticated users by leveraging `lua-resty-session` thus offering
a configurable choice between storing the session state in a client-side browser cookie or use
in of the server-side storage mechanisms `shared-memory|memcache|redis`.

It supports server-wide caching of resolved Discovery documents and validated Access Tokens.

It can be used as a reverse proxy terminating OAuth/OpenID Connect in front of an origin server so that
the origin server/services can be protected with the relevant standards without implementing those on
the server itself.

## Dependencies

**lua-resty-openidc** depends on the following packages:

- [NGINX](http://nginx.org/) and [`ngx_devel_kit`](https://github.com/simpl/ngx_devel_kit)
- [Lua](http://www.lua.org/) or [LuaJIT](http://luajit.org/luajit.html)
- [`lua-nginx-module`](https://github.com/openresty/lua-nginx-module)
- [`lua-cjson`](http://www.kyne.com.au/~mark/software/lua-cjson.php)
- [`lua-resty-string`](https://github.com/openresty/lua-resty-string)

The dependencies above come automatically with [OpenResty](http://openresty.org/). You will need
to install two extra pure-Lua dependencies that implement session management and HTTP client functions:

- [`lua-resty-http`](https://github.com/pintsized/lua-resty-http)
- [`lua-resty-session`](https://github.com/bungle/lua-resty-session)

Typically - when running as an OpenID Connect RP or an OAuth 2.0 server that consumes JWT
access tokens - you'll also need to install the following dependency:

- [`lua-resty-jwt`](https://github.com/cdbattags/lua-resty-jwt)

The `lua-resty-jwt` dependency above is *not* required when running as an OAuth 2.0 Resource Server (only) using remote
introspection for access token validation.

## Installation

If you're using `opm` execute the following:

     opm install zmartzone/lua-resty-openidc

If you're using `luarocks` execute the following:

     luarocks install lua-resty-openidc

Otherwise copy `openidc.lua` somewhere in your `lua_package_path` under a directory named `resty`.
If you are using [OpenResty](http://openresty.org/), the default location would be `/usr/local/openresty/lualib/resty`.

## Sample Configuration for Google+ Signin

Sample `nginx.conf` configuration for authenticating users against Google+ Signin, protecting a reverse-proxied path.

```nginx
events {
  worker_connections 128;
}

http {

  lua_package_path '~/lua/?.lua;;';

  resolver 8.8.8.8;

  lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
  lua_ssl_verify_depth 5;

  # cache for discovery metadata documents
  lua_shared_dict discovery 1m;
  # cache for JWKs
  lua_shared_dict jwks 1m;

  # NB: if you have "lua_code_cache off;", use:
  # set $session_secret xxxxxxxxxxxxxxxxxxx;
  # see: https://github.com/bungle/lua-resty-session#notes-about-turning-lua-code-cache-off

  server {
    listen 8080;

    location / {

      access_by_lua_block {

          local opts = {
             -- the full redirect URI must be protected by this script
             -- if the URI starts with a / the full redirect URI becomes
             -- ngx.var.scheme.."://"..ngx.var.http_host..opts.redirect_uri
             -- unless the scheme was overridden using opts.redirect_uri_scheme or an X-Forwarded-Proto header in the incoming request
             redirect_uri = "https://MY_HOST_NAME/redirect_uri",
             -- up until version 1.6.1 you'd specify
             -- redirect_uri_path = "/redirect_uri",
             -- and could not set the hostname

             -- The discovery endpoint of the OP. Enable to get the URI of all endpoints (Token, introspection, logout...)
             discovery = "https://accounts.google.com/.well-known/openid-configuration",

             -- Access to OP Token endpoint requires an authentication. Several authentication modes are supported:
             --token_endpoint_auth_method = ["client_secret_basic"|"client_secret_post"|"private_key_jwt"|"client_secret_jwt"],
             -- o If token_endpoint_auth_method is set to "client_secret_basic", "client_secret_post", or "client_secret_jwt", authentication to Token endpoint is using client_id and client_secret
             --   For non compliant OPs to OAuth 2.0 RFC 6749 for client Authentication (cf. https://tools.ietf.org/html/rfc6749#section-2.3.1)
             --   client_id and client_secret MUST be invariant when url encoded
             client_id = "<client_id>",
             client_secret = "<client_secret>",
             -- o If token_endpoint_auth_method is set to "private_key_jwt" authentication to Token endpoint is using client_id, client_rsa_private_key and client_rsa_private_key_id to compute a signed JWT
             --   client_rsa_private_key is the RSA private key to be used to sign the JWT generated by lua-resty-openidc for authentication to the OP
             --   client_rsa_private_key_id (optional) is the key id to be set in the JWT header to identify which public key the OP shall use to verify the JWT signature
             --client_id = "<client_id>",
             --client_rsa_private_key=[[-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAiThmpvXBYdur716D2q7fYKirKxzZIU5QrkBGDvUOwg5izcTv
[...]
h2JHukolz9xf6qN61QMLSd83+kwoBr2drp6xg3eGDLIkQCQLrkY=
-----END RSA PRIVATE KEY-----]],
             --client_rsa_private_key_id="key id#1",
             --   Life duration expressed in seconds of the signed JWT generated by lua-resty-openidc for authentication to the OP.
             --   (used when token_endpoint_auth_method is set to "private_key_jwt" or "client_secret_jwt" authentication). Default is 60 seconds.
             --client_jwt_assertion_expires_in = 60,
             -- When using https to any OP endpoints, enforcement of SSL certificate check can be mandated ("yes") or not ("no").
             --ssl_verify = "no",
             -- Connection keepalive with the OP can be enabled ("yes") or disabled ("no").
             --keepalive = "no",

             --response_mode=form_post can be used to make lua-resty-openidc use the [OAuth 2.0 Form Post Response Mode](https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html). *Note* for modern browsers you will need to set [`$session_cookie_samesite`](https://github.com/bungle/lua-resty-session#string-sessioncookiesamesite) to `None` with form_post unless your OpenID Connect Provider and Relying Party share the same domain.
             --authorization_params = { hd="zmartzone.eu" },
             --scope = "openid email profile",
             -- Refresh the users id_token after 900 seconds without requiring re-authentication
             --refresh_session_interval = 900,
             --iat_slack = 600,
             --redirect_uri_scheme = "https",
             --logout_path = "/logout",
             --redirect_after_logout_uri = "/",
             -- Where should the user be redirected after logout from the RP. This option overides any end_session_endpoint that the OP may have provided in the discovery response.
             --redirect_after_logout_with_id_token_hint = true,
             -- Whether the redirection after logout should include the id token as an hint (if available). This option is used only if redirect_after_logout_uri is set.
             --post_logout_redirect_uri = "https://www.zmartzone.eu/logoutSuccessful",
             -- Where does the RP requests that the OP redirects the user after logout. If this option is set to a relative URI, it will be relative to the OP's logout endpoint, not the RP's.

             --accept_none_alg = false
             -- if your OpenID Connect Provider doesn't sign its id tokens
             -- (uses the "none" signature algorithm) then set this to true.

             --accept_unsupported_alg = true
             -- if you want to reject tokens signed using an algorithm
             -- not supported by lua-resty-jwt set this to false. If
             -- you leave it unset or set it to true, the token signature will not be
             -- verified when an unsupported algorithm is used.

             --renew_access_token_on_expiry = true
             -- whether this plugin shall try to silently renew the access token once it is expired if a refresh token is available.
             -- if it fails to renew the token, the user will be redirected to the authorization endpoint.
             --access_token_expires_in = 3600
             -- Default lifetime in seconds of the access_token if no expires_in attribute is present in the token endpoint response.

             --access_token_expires_leeway = 0
             --  Expiration leeway for access_token renewal. If this is set, renewal will happen access_token_expires_leeway seconds before the token expiration. This avoids errors in case the access_token just expires when arriving to the OAuth Resource Server.

             --force_reauthorize = false
             -- When force_reauthorize is set to true the authorization flow will be executed even if a token has been cached already
             --session_contents = {id_token=true}
             -- Whitelist of session content to enable. This can be used to reduce the session size.
             -- When not set everything will be included in the session.
             -- Available are:
             -- id_token, enc_id_token, user, access_token (includes refresh token)

             -- You can specify timeouts for connect/send/read as a single number (setting all timeouts) or as a table. Values are in milliseconds
             -- timeout = 1000
             -- timeout = { connect = 500, send = 1000, read = 1000 }

             --use_nonce = false
             -- By default the authorization request includes the
             -- nonce paramter. You can use this option to disable it
             -- which may be necessary when talking to a broken OpenID
             -- Connect provider that ignores the paramter as the
             -- id_token will be rejected otherwise.

             --revoke_tokens_on_logout = false
             -- When revoke_tokens_on_logout is set to true a logout notifies the authorization server that previously obtained refresh and access tokens are no longer needed. This requires that revocation_endpoint is discoverable.
             -- If there is no revocation endpoint supplied or if there are errors on revocation the user will not be notified and the logout process continues normally.

             -- Optional : use outgoing proxy to the OpenID Connect provider endpoints with the proxy_opts table :
             -- this requires lua-resty-http >= 0.12
             -- proxy_opts = {
             --    http_proxy  = "http://<proxy_host>:<proxy_port>/",
             --    https_proxy = "http://<proxy_host>:<proxy_port>/"
             -- }

             -- Lifecycle Hooks
             --
             -- lifecycle = {
             --    on_created = handle_created,
             --    on_authenticated = handle_authenticated,
             --    on_regenerated = handle_regenerated
             --    on_logout = handle_logout
             -- }
             --
             -- where `handle_created`, `handle_authenticated`, `handle_regenerated` and `handle_logout` are callables
             -- accepting a single argument `session`
             --
             --  -- `on_created` hook is invoked *after* a session has been created in
             --     `openidc_authorize` immediately prior to saving the session
             --  -- `on_authenticated` hook is invoked *after* receiving authorization response in
             --     `openidc_authorization_response` immediately prior to saving the session
             --     Starting with lua-resty-openidc 1.7.5 this receives the decoded id_token as second and the response of the token endpoint as third argument
             --  -- `on_regenerated` is invoked immediately after the
                     a new access token has been obtained via token
                     refresh and is called with the regenerated session table
             --  -- `on_logout` hook is invoked *before* a session is destroyed in
             --     `openidc_logout`
             --
             --  Any, all or none of the hooks may be used. Empty `lifecycle` does nothing.
             --  A hook that returns a truthy value causes the lifecycle action they are taking part of to fail.

             -- Optional : add decorator for HTTP request that is
             -- applied when lua-resty-openidc talks to the OpenID Connect
             -- provider directly. Can be used to provide extra HTTP headers
             -- or add other similar behavior.
             -- http_request_decorator = function(req)
             --   local h = req.headers or {}
             --   h[EXTRA_HEADER] = 'my extra header'
             --   req.headers = h
             --   return req
             -- end,

             -- use_pkce = false,
             -- when set to true the "Proof Key for Code Exchange" as
             -- defined in RFC 7636 will be used. The code challenge
             -- method will alwas be S256

          }

          -- call authenticate for OpenID Connect user authentication
          local res, err = require("resty.openidc").authenticate(opts)

          if err then
            ngx.status = 500
            ngx.say(err)
            ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
          end

          -- at this point res is a Lua table with 3 keys:
          --   id_token    : a Lua table with the claims from the id_token (required)
          --   access_token: the access token (optional)
          --   user        : a Lua table with the claims returned from the user info endpoint (optional)

          --if res.id_token.hd ~= "zmartzone.eu" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end

          --if res.user.email ~= "hans.zandbelt@zmartzone.eu" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end

          -- set headers with user info: this will overwrite any existing headers
          -- but also scrub(!) them in case no value is provided in the token
          ngx.req.set_header("X-USER", res.id_token.sub)
      }

      proxy_pass http://localhost:80;
    }
  }
}
```

## Check authentication only

```lua
-- check session, but do not redirect to auth if not already logged in
local res, err = require("resty.openidc").authenticate(opts, nil, "pass")
```

## Check authentication only and deny unauthenticated access

```lua
-- check session, do not redirect to auth if not already logged in but return an error instead
local res, err = require("resty.openidc").authenticate(opts, nil, "deny")
```

## Sessions and Locking

The `authenticate` function returns the current session object as its
forth return argument. If you have configured lua-resty-session to use
a server side storage backend that uses locking, the session may still
be locked when it is returned. In this case you may want to close it
explicitly

```lua
local res, err, target, session = require("resty.openidc").authenticate(opts)
session:close()
```

## Caching

lua-resty-openidc can use [shared memory
caches](https://github.com/openresty/lua-nginx-module/#lua_shared_dict)
for several things. If you want it to use the caches, you must use
`lua_shared_dict` in your `nginx.conf` file.

Currently up to four caches are used

* the cache named `discovery` stores the OpenID Connect Disovery
  metadata of your OpenID Connect Provider. Cache items expire after
  24 hours unless overriden by `opts.discovery_expires_in` (a value
  given in seconds) . This cache will store one item per issuer URI
  and you can look up the discovery document yourself to get an
  estimate for the size required - usually a few kB per OpenID Connect
  Provider.
* the cache named `jwks` stores the key material of your OpenID
  Connect Provider if it is provided via the JWKS endpoint. Cache
  items expire after 24 hours unless overriden by
  `opts.jwks_expires_in`. This cache will store one item per JWKS URI
  and you can look up the jwks yourself to get an estimate for the
  size required - usually a few kB per OpenID Connect Provider.
* the cache named `introspection` stores the result of OAuth2 token
  introspection. Cache items expire when the corresponding token
  expires. Tokens with unknown expiry are not cached at all. This
  cache will contain one entry per introspected access token - usually
  this will be a few kB per token.
* the cache named `jwt_verification` stores the result of JWT
  verification.  Cache items expire when the corresponding token
  expires. Tokens with unknown expiry are not cached for two
  minutes. This cache will contain one entry per verified JWT -
  usually this will be a few kB per token.

## Caching of Introspection and JWT Verification Results

Note the `jwt_verification` and `introspection` caches are shared
between all configured locations. If you are using locations with
different `opts` configuration the shared cache may allow a token that
is valid for only one location to be accepted by another if it is read
from the cache. In order to avoid cache confusion it is recommended to
set `opts.cache_segment` to unique strings for each set of related
locations.

## Revoke tokens

The `revoke_tokens(opts, session)` function revokes the current refresh and access token. In contrast to a full logout, the session cookie will not be destroyed and the endsession endpoint will not be called. The function returns `true` if both tokens were revoked successfully. This function might be helpful in scenarios where you want to destroy/remove a session from the server side.

With `revoke_token(opts, token_type_hint, token)` it is also possible to revoke a specific token. `token_type_hint` can usually be `refresh_token` or `access_token`.

## Sample Configuration for OAuth 2.0 JWT Token Validation

Sample `nginx.conf` configuration for verifying Bearer JWT Access Tokens against a pre-configured secret/key.
Once successfully verified, the NGINX server may function as a reverse proxy to an internal origin server.

```nginx
events {
  worker_connections 128;
}

http {

  lua_package_path '~/lua/?.lua;;';

  resolver 8.8.8.8;

  # cache for JWT verification results
  lua_shared_dict jwt_verification 10m;

  server {
    listen 8080;

    location /api {

      access_by_lua '

          local opts = {

            -- 1. example of a shared secret for HS??? signature verification
            --symmetric_key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            -- in versions up to 1.6.1 this option's key would have been secret
            -- rather than symmetric_key

            -- 2. another example of a public cert for RS??? signature verification
            public_key = [[-----BEGIN CERTIFICATE-----
MIIC0DCCAbigAwIBAgIGAVSbMZs1MA0GCSqGSIb3DQEBCwUAMCkxCzAJBgNVBAYTAlVTMQwwCgYD
VQQKEwNibGExDDAKBgNVBAMTA2JsYTAeFw0xNjA1MTAxNTAzMjBaFw0yNjA1MDgxNTAzMjBaMCkx
CzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNibGExDDAKBgNVBAMTA2JsYTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAIcLtHjX2GFxYv1033dvfohyCU6nsuR1qoDXfHTG3Mf/Yj4BfLHtMjJr
nR3sgHItH3B6qZPnfErfsN0LP4uZ10/74CrWVqT5dy6ecXMqYtz/KNJ8rG0vY8vltc417AU4fie8
gyeWv/Z6wHWUCf3NHRV8GfFgfuvywgUpHo8ujpUPFr+zrPr8butrzJPq1h3+r0f5P45tfWOdpjCT
gsTzK6urUG0k3WkwdDYapL3wRCAw597nYfgKzzXuh9N0ZL3Uj+eJ6BgCzUZDLXABpMBZfk6hmmzp
cAFV4nTf1AaAs/EOwVE0YgZBJiBrueMcteAIxKrKjEHgThU2Zs9gN9cSFicCAwEAATANBgkqhkiG
9w0BAQsFAAOCAQEAQLU1A58TrSwrEccCIy0wxiGdCwQbaNMohzirc41zRMCXleJXbtsn1vv85J6A
RmejeH5f/JbDqRRRArGMdLooGbqjWG/lwZT456Q6DXqF2plkBvh37kp/GjthGyR8ODJn5ekZwxuB
OcTuruRhqYOIJjiYZSgK/P0zUw1cjLwUJ9ig/O6ozYmof83974fygA/wK3SgFNEoFlTkTpOvZhVW
9kLfCVA/CRBfJNKnz5PWBBxd/3XSEuP/fcWqKGTy7zZso4MTB0NKgWO4duGTgMyZbM4onJPyA0CY
lAc5Csj0o5Q+oEhPUAVBIF07m4rd0OvAVPOCQ2NJhQSL1oWASbf+fg==
-----END CERTIFICATE-----]],
            -- in versions up to 1.6.1 this option's key would have been secret
            -- rather than public_key

            -- 3. alternatively one can point to a so-called Discovery document that
            -- contains "jwks_uri" entry; the jwks endpoint must provide either an "x5c" entry
            -- or both the "n" modulus and "e" exponent entries for RSA signature verification
            -- discovery = "https://accounts.google.com/.well-known/openid-configuration",

             -- the signature algorithm that you expect has been used;
             -- can be a single string or a table.
             -- You should set this for security reasons in order to
             -- avoid accepting a token claiming to be signed by HMAC
             -- using a public RSA key.
             --token_signing_alg_values_expected = { "RS256" }

             -- if you want to accept unsigned tokens (using the
             -- "none" signature algorithm) then set this to true.
             --accept_none_alg = false

             -- if you want to reject tokens signed using an algorithm
             -- not supported by lua-resty-jwt set this to false. If
             -- you leave it unset, the token signature will not be
             -- verified at all.
             --accept_unsupported_alg = true

             -- the expiration time in seconds for jwk cache, default is 1 day.
             --jwk_expires_in = 24 * 60 * 60

             -- It may be necessary to force verification for a bearer token and ignore the existing cached
             -- verification results. If so you need to set set the jwt_verification_cache_ignore option to true.
             -- jwt_verification_cache_ignore = true

             -- optional name of a cache-segment if you need separate
             -- caches for differently configured locations
             -- cache_segment = 'api'
          }

          -- call bearer_jwt_verify for OAuth 2.0 JWT validation
          local res, err = require("resty.openidc").bearer_jwt_verify(opts)

           if err or not res then
            ngx.status = 403
            ngx.say(err and err or "no access_token provided")
            ngx.exit(ngx.HTTP_FORBIDDEN)
          end

          -- at this point res is a Lua table that represents the (validated) JSON
          -- payload in the JWT token; now we typically do not want to allow just any
          -- token that was issued by the Authorization Server but we want to apply
          -- some access restrictions via client IDs or scopes

          --if res.scope ~= "edit" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end

          --if res.client_id ~= "ro_client" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end
      ';

       proxy_pass http://localhost:80;
    }
  }
}
```

## Sample Configuration for PingFederate OAuth 2.0

Sample `nginx.conf` configuration for validating Bearer Access Tokens against a PingFederate OAuth 2.0 Authorization Server.

```nginx
events {
  worker_connections 128;
}

http {

  lua_package_path '~/lua/?.lua;;';

  resolver 8.8.8.8;

  lua_ssl_trusted_certificate /opt/local/etc/openssl/cert.pem;
  lua_ssl_verify_depth 5;

  # cache for validation results
  lua_shared_dict introspection 10m;

  server {
    listen 8080;

    location /api {

      access_by_lua '

          local opts = {
             introspection_endpoint="https://localhost:9031/as/introspect.oauth2",
             client_id="rs_client",
             client_secret="2Federate",
             ssl_verify = "no",

             -- Defaults to "exp" - Controls the TTL of the introspection cache
             -- https://tools.ietf.org/html/rfc7662#section-2.2
             -- introspection_expiry_claim = "exp"

             -- optional name of a cache-segment if you need separate
             -- caches for differently configured locations
             -- cache_segment = 'api'
          }

          -- call introspect for OAuth 2.0 Bearer Access Token validation
          local res, err = require("resty.openidc").introspect(opts)

          if err then
            ngx.status = 403
            ngx.say(err)
            ngx.exit(ngx.HTTP_FORBIDDEN)
          end

          -- at this point res is a Lua table that represents the JSON
          -- object returned from the introspection/validation endpoint

          --if res.scope ~= "edit" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end

          --if res.client_id ~= "ro_client" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end
      ';
    }
  }
}
```

## Sample Configuration for passing bearer OAuth 2.0 access tokens as cookie

Sample `nginx.conf` configuration for validating Bearer Access Tokens passed as cookie against a ORY/Hydra Authorization Server.

```nginx
events {
  worker_connections 128;
}

http {

  lua_package_path '~/lua/?.lua;;';

  resolver 8.8.8.8;

  lua_ssl_trusted_certificate /opt/local/etc/openssl/cert.pem;
  lua_ssl_verify_depth 5;

  # cache for validation results
  lua_shared_dict introspection 10m;

  server {
    listen 8080;

    location /api {

      access_by_lua '

          local opts = {
             -- sets the URI of the introspection endpoint
             introspection_endpoint="https://localhost:9031/oauth2/introspect",

             -- alternatively if your OAuth2 Provider provides a discovery document that contains the
             -- introspection_endpoint claim you can leave the introspection_endpoint option
             -- unset and instead use
             -- discovery = "https://my-oauth2-provider/.well-known/oauth-authorization-server",

             client_id="admin",
             client_secret="demo-password",
             ssl_verify = "no",

             -- Defines the interval in seconds after which a cached and introspected access token needs
             -- to be refreshed by introspecting (and validating) it again against the Authorization Server.
             -- When not defined the value is 0, which means it only expires after the `exp` (or alternative,
             -- see introspection_expiry_claim) hint as returned by the Authorization Server
             -- introspection_interval = 60,

             -- Defines the way in which bearer OAuth 2.0 access tokens can be passed to this Resource Server.
             -- "cookie" as a cookie header called "PA.global" or using the name specified after ":"
             -- "header" "Authorization: bearer" header
             -- When not defined the default "Authorization: bearer" header is used
             -- auth_accept_token_as = "cookie:PA",

             -- If header is used header field is Authorization
             -- auth_accept_token_as_header_name = "cf-Access-Jwt-Assertion"

             -- Authentication method for the OAuth 2.0 Authorization Server introspection endpoint,
             -- Used to authenticate the client to the introspection endpoint with a client_id/client_secret
             -- Defaults to "client_secret_post"
             -- introspection_endpoint_auth_method = "client_secret_basic",

             -- Specify the names of cookies separated by whitespace to pickup from the browser and send along on backchannel
             -- calls to the OP and AS endpoints.
             -- When not defined, no such cookies are sent.
             -- pass_cookies = "JSESSION"

             -- Defaults to "exp" - Controls the TTL of the introspection cache
             -- https://tools.ietf.org/html/rfc7662#section-2.2
             -- introspection_expiry_claim = "exp"

             -- It may be necessary to force an introspection call for an access_token and ignore the existing cached
             -- introspection results. If so you need to set set the introspection_cache_ignore option to true.
             -- introspection_cache_ignore = true

             -- optional name of a cache-segment if you need separate
             -- caches for differently configured locations
             -- cache_segment = 'api'
          }

          -- call introspect for OAuth 2.0 Bearer Access Token validation
          local res, err = require("resty.openidc").introspect(opts)

          if err then
            ngx.status = 403
            ngx.say(err)
            ngx.exit(ngx.HTTP_FORBIDDEN)
          end

          -- at this point res is a Lua table that represents the JSON
          -- object returned from the introspection/validation endpoint

          --if res.scope ~= "edit" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end

          --if res.client_id ~= "ro_client" then
          --  ngx.exit(ngx.HTTP_FORBIDDEN)
          --end
      ';
    }
  }
}
```

## Logging

Logging can be customized, including using custom logger and remapping OpenIDC's
default log levels, e.g:

```lua
local openidc = require("resty.openidc")
openidc.set_logging(nil, { DEBUG = ngx.INFO })
```

## Running Tests

We've created a dockerized setup for the test in order to simplify the
installation of dependencies.

In order to run the tests perform

```shell
$ docker build -f tests/Dockerfile . -t lua-resty-openidc/test
$ docker run -it --rm lua-resty-openidc/test:latest
```

if you want to create
[luacov](https://keplerproject.github.io/luacov/) coverage while
testing use

```shell
$ docker run -it --rm -e coverage=t lua-resty-openidc/test:latest
```

as the second command

## Support

For generic questions, see the Wiki pages with Frequently Asked Questions at:
[https://github.com/zmartzone/lua-resty-openidc/wiki](https://github.com/zmartzone/lua-resty-openidc/wiki)
Any questions/issues should go to the Github Discussons or Issues tracker.

## Disclaimer

*This software is open sourced by ZmartZone IAM but not supported commercially as such.
Any questions/issues should go to the Github Discussions or Issues tracker.
See also the DISCLAIMER file in this directory.*

redpajama_set_name: RedPajamaGithub


text:
ldap_mod_del() - Basic modify operation
--CREDITS--
Patrick Allaert <patrickallaert@php.net>
# Belgian PHP Testfest 2009
--SKIPIF--
<?php require_once('skipif.inc'); ?>
<?php require_once('skipifbindfailure.inc'); ?>
--FILE--
<?php
require "connect.inc";

$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
insert_dummy_data($link, $base);

$entry = array(
	"description" => "user A"
);

var_dump(
	ldap_mod_del($link, "cn=userA,$base", $entry),
	ldap_get_entries(
		$link,
		ldap_search($link, "$base", "(description=user A)")
	)
);
?>
===DONE===
--CLEAN--
<?php
require "connect.inc";

$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);

remove_dummy_data($link, $base);
?>
--EXPECT--
bool(true)
array(1) {
  ["count"]=>
  int(0)
}
===DONE===


text:
include(hunter_add_version)
include(hunter_cacheable)
include(hunter_download)
include(hunter_pick_scheme)

hunter_add_version(
    PACKAGE_NAME
    STB
    VERSION
    "1.0.0-p1"
    URL
    "https://github.com/headupinclouds/STB/archive/v1.0.0-p1.tar.gz"
    SHA1
    39548b5ff6f76ee202d12af79e3932eb2d96fe2a
)

hunter_pick_scheme(DEFAULT url_sha1_cmake)
hunter_cacheable(STB)
hunter_download(PACKAGE_NAME STB)


text:
module ArrayLike::Slicable

  module ClassMethods
    # A slicable class gets its own subclass of [`ArrayLike::Slice`](slice.html)
    # that includes any [read-only](read_only.html) `ArrayLike` modules that are
    # included into your collection.  This allows each slice to behave very
    # closely to your overall collection.
    INHERITED_SLICE_MODULES = [
      :Coercion,
      :Combinatorics,
      :Comparison,
      :Enumeration,
      :Indexing,
      :Inspection,
      :SetLikeOperations,
    ]

    # Constructs a new slice.
    def new_slice(*args)
      # It also lazy-initializes the `Slice` subclass with the modules that are
      # whitelisted by `INHERITED_SLICE_MODULES`.
      unless defined? @_slice_class_initialized
        included_modules.each do |mod|
          if mod.name && INHERITED_SLICE_MODULES.include?(mod.name.sub(/^ArrayLike::/, "").to_sym)
            self::Slice.send(:include, mod)
          end
        end

        @_slice_class_initialized = true
      end

      self::Slice.new(*args)
    end
  end

  def self.make_slicable(klass)
    # Since we copy modules from the container class into the slice class on
    # [`new_slice`](#new_slice), we need to be careful not to have a never-
    # ending stack of `Slice` classes.
    return if klass.ancestors.include? ::ArrayLike::Slice

    # Likewise, we don't want to double-init
    if klass.const_defined? :Slice
      return if klass.const_get(:Slice).ancestors.include? ::ArrayLike::Slice

      raise ArgumentError, "Attempting to make #{klass.inspect} slicable, but it already defines #{klass.const_get(:Slice).inspect}!"
    end

    klass.const_set(:Slice, Class.new(::ArrayLike::Slice))

    klass.extend(ClassMethods)
  end

  # As an internal convenience, any `ArrayLike` module that includes this will
  # propagate it all the way out to any third party class that requires a
  # `Slice` subclass.
  def self.propagate(mod)
    return unless mod.name && mod.name.start_with?("ArrayLike::")

    if mod.respond_to? :included
      raise ArgumentError, "#{self.inspect}.propagate does not support modules that define included!"
    end

    def mod.included(other_mod)
      if other_mod.is_a? Class
        ::ArrayLike::Slicable.make_slicable(other_mod)
      else
        # Insiduous!  Propagate us until we hit a class
        ::ArrayLike::Slicable.propagate(other_mod)
      end
    end
  end

  propagate(self)

end


text:
#include "radeon_dataflow.h"

#include "radeon_compiler.h"

struct updatemask_state {
	unsigned char Output[RC_REGISTER_MAX_INDEX];
	unsigned char Temporary[RC_REGISTER_MAX_INDEX];
	unsigned char Address;
	unsigned char Special[RC_NUM_SPECIAL_REGISTERS];
};

struct instruction_state {
	unsigned char WriteMask:4;
	unsigned char WriteALUResult:1;
	unsigned char SrcReg[3];
};

struct loopinfo {
	struct updatemask_state * Breaks;
	unsigned int BreakCount;
	unsigned int BreaksReserved;
};

struct branchinfo {
	unsigned int HaveElse:1;

	struct updatemask_state StoreEndif;
	struct updatemask_state StoreElse;
};

struct deadcode_state {
	struct radeon_compiler * C;
	struct instruction_state * Instructions;

	struct updatemask_state R;

	struct branchinfo * BranchStack;
	unsigned int BranchStackSize;
	unsigned int BranchStackReserved;

	struct loopinfo * LoopStack;
	unsigned int LoopStackSize;
	unsigned int LoopStackReserved;
};

static void or_updatemasks(
	struct updatemask_state * dst,
	struct updatemask_state * a,
	struct updatemask_state * b)
{
	for(unsigned int i = 0; i < RC_REGISTER_MAX_INDEX; ++i) {
		dst->Output[i] = a->Output[i] | b->Output[i];
		dst->Temporary[i] = a->Temporary[i] | b->Temporary[i];
	}

	for(unsigned int i = 0; i < RC_NUM_SPECIAL_REGISTERS; ++i)
		dst->Special[i] = a->Special[i] | b->Special[i];

	dst->Address = a->Address | b->Address;
}

static void push_break(struct deadcode_state *s)
{
	struct loopinfo * loop = &s->LoopStack[s->LoopStackSize - 1];
	memory_pool_array_reserve(&s->C->Pool, struct updatemask_state,
		loop->Breaks, loop->BreakCount, loop->BreaksReserved, 1);

	memcpy(&loop->Breaks[loop->BreakCount++], &s->R, sizeof(s->R));
}

static void push_loop(struct deadcode_state * s)
{
	memory_pool_array_reserve(&s->C->Pool, struct loopinfo, s->LoopStack,
			s->LoopStackSize, s->LoopStackReserved, 1);
	memset(&s->LoopStack[s->LoopStackSize++], 0, sizeof(struct loopinfo));
}

static void push_branch(struct deadcode_state * s)
{
	memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack,
			s->BranchStackSize, s->BranchStackReserved, 1);

	struct branchinfo * branch = &s->BranchStack[s->BranchStackSize++];
	branch->HaveElse = 0;
	memcpy(&branch->StoreEndif, &s->R, sizeof(s->R));
}

static unsigned char * get_used_ptr(struct deadcode_state *s, rc_register_file file, unsigned int index)
{
	if (file == RC_FILE_OUTPUT || file == RC_FILE_TEMPORARY) {
		if (index >= RC_REGISTER_MAX_INDEX) {
			rc_error(s->C, "%s: index %i is out of bounds for file %i\n", __FUNCTION__, index, file);
			return 0;
		}

		if (file == RC_FILE_OUTPUT)
			return &s->R.Output[index];
		else
			return &s->R.Temporary[index];
	} else if (file == RC_FILE_ADDRESS) {
		return &s->R.Address;
	} else if (file == RC_FILE_SPECIAL) {
		if (index >= RC_NUM_SPECIAL_REGISTERS) {
			rc_error(s->C, "%s: special file index %i out of bounds\n", __FUNCTION__, index);
			return 0;
		}

		return &s->R.Special[index];
	}

	return 0;
}

static void mark_used(struct deadcode_state * s, rc_register_file file, unsigned int index, unsigned int mask)
{
	unsigned char * pused = get_used_ptr(s, file, index);
	if (pused)
		*pused |= mask;
}

static void update_instruction(struct deadcode_state * s, struct rc_instruction * inst)
{
	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
	struct instruction_state * insts = &s->Instructions[inst->IP];
	unsigned int usedmask = 0;

	if (opcode->HasDstReg) {
		unsigned char * pused = get_used_ptr(s, inst->U.I.DstReg.File, inst->U.I.DstReg.Index);
		if (pused) {
			usedmask = *pused & inst->U.I.DstReg.WriteMask;
			if (!inst->U.I.DstReg.RelAddr)
				*pused &= ~usedmask;
		}

		if (inst->U.I.DstReg.RelAddr)
			mark_used(s, RC_FILE_ADDRESS, 0, RC_MASK_X);
	}

	insts->WriteMask |= usedmask;

	if (inst->U.I.WriteALUResult) {
		unsigned char * pused = get_used_ptr(s, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT);
		if (pused && *pused) {
			if (inst->U.I.WriteALUResult == RC_ALURESULT_X)
				usedmask |= RC_MASK_X;
			else if (inst->U.I.WriteALUResult == RC_ALURESULT_W)
				usedmask |= RC_MASK_W;

			*pused = 0;
			insts->WriteALUResult = 1;
		}
	}

	unsigned int srcmasks[3];
	rc_compute_sources_for_writemask(inst, usedmask, srcmasks);

	for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
		unsigned int refmask = 0;
		unsigned int newsrcmask = srcmasks[src] & ~insts->SrcReg[src];
		insts->SrcReg[src] |= newsrcmask;

		for(unsigned int chan = 0; chan < 4; ++chan) {
			if (GET_BIT(newsrcmask, chan))
				refmask |= 1 << GET_SWZ(inst->U.I.SrcReg[src].Swizzle, chan);
		}

		/* get rid of spurious bits from ZERO, ONE, etc. swizzles */
		refmask &= RC_MASK_XYZW;

		if (!refmask)
			continue;

		mark_used(s, inst->U.I.SrcReg[src].File, inst->U.I.SrcReg[src].Index, refmask);

		if (inst->U.I.SrcReg[src].RelAddr)
			mark_used(s, RC_FILE_ADDRESS, 0, RC_MASK_X);
	}
}

static void mark_output_use(void * data, unsigned int index, unsigned int mask)
{
	struct deadcode_state * s = data;

	mark_used(s, RC_FILE_OUTPUT, index, mask);
}

void rc_dataflow_deadcode(struct radeon_compiler * c, void *user)
{
	struct deadcode_state s;
	unsigned int nr_instructions;
	unsigned has_temp_reladdr_src = 0;
	rc_dataflow_mark_outputs_fn dce = (rc_dataflow_mark_outputs_fn)user;

	/* Give up if there is relative addressing of destination operands. */
	for(struct rc_instruction * inst = c->Program.Instructions.Next;
	    inst != &c->Program.Instructions;
	    inst = inst->Next) {
		const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
		if (opcode->HasDstReg &&
		    inst->U.I.DstReg.WriteMask &&
		    inst->U.I.DstReg.RelAddr) {
			return;
		}
	}

	memset(&s, 0, sizeof(s));
	s.C = c;

	nr_instructions = rc_recompute_ips(c);
	s.Instructions = memory_pool_malloc(&c->Pool, sizeof(struct instruction_state)*nr_instructions);
	memset(s.Instructions, 0, sizeof(struct instruction_state)*nr_instructions);

	dce(c, &s, &mark_output_use);

	for(struct rc_instruction * inst = c->Program.Instructions.Prev;
	    inst != &c->Program.Instructions;
	    inst = inst->Prev) {
		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);

		switch(opcode->Opcode){
		/* Mark all sources in the loop body as used before doing
		 * normal deadcode analysis.  This is probably not optimal.
		 */
		case RC_OPCODE_ENDLOOP:
		{
			int endloops = 1;
			struct rc_instruction *ptr;
			for(ptr = inst->Prev; endloops > 0; ptr = ptr->Prev){
				opcode = rc_get_opcode_info(ptr->U.I.Opcode);
				if(ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){
					endloops--;
					continue;
				}
				if(ptr->U.I.Opcode == RC_OPCODE_ENDLOOP){
					endloops++;
					continue;
				}
				if(opcode->HasDstReg){
					int src = 0;
					unsigned int srcmasks[3];
					rc_compute_sources_for_writemask(ptr,
						ptr->U.I.DstReg.WriteMask, srcmasks);
					for(src=0; src < opcode->NumSrcRegs; src++){
						mark_used(&s,
							ptr->U.I.SrcReg[src].File,
							ptr->U.I.SrcReg[src].Index,
							srcmasks[src]);
					}
				}
			}
			push_loop(&s);
			break;
		}
		case RC_OPCODE_BRK:
			push_break(&s);
			break;
		case RC_OPCODE_BGNLOOP:
		{
			unsigned int i;
			struct loopinfo * loop = &s.LoopStack[s.LoopStackSize-1];
			for(i = 0; i < loop->BreakCount; i++) {
				or_updatemasks(&s.R, &s.R, &loop->Breaks[i]);
			}
			break;
		}
		case RC_OPCODE_CONT:
			break;
		case RC_OPCODE_ENDIF:
			push_branch(&s);
			break;
		default:
			if (opcode->IsFlowControl && s.BranchStackSize) {
				struct branchinfo * branch = &s.BranchStack[s.BranchStackSize-1];
				if (opcode->Opcode == RC_OPCODE_IF) {
					or_updatemasks(&s.R,
							&s.R,
							branch->HaveElse ? &branch->StoreElse : &branch->StoreEndif);

					s.BranchStackSize--;
				} else if (opcode->Opcode == RC_OPCODE_ELSE) {
					if (branch->HaveElse) {
						rc_error(c, "%s: Multiple ELSE for one IF/ENDIF\n", __FUNCTION__);
					} else {
						memcpy(&branch->StoreElse, &s.R, sizeof(s.R));
						memcpy(&s.R, &branch->StoreEndif, sizeof(s.R));
						branch->HaveElse = 1;
					}
				} else {
					rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
				}
			}

			if (!has_temp_reladdr_src) {
				for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
					if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY &&
					    inst->U.I.SrcReg[i].RelAddr) {
						/* If there is a register read from a temporary file with relative addressing,
						 * mark all preceding written registers as used. */
						for (struct rc_instruction *ptr = inst->Prev;
						     ptr != &c->Program.Instructions;
						     ptr = ptr->Prev) {
							opcode = rc_get_opcode_info(ptr->U.I.Opcode);
							if (opcode->HasDstReg &&
							    ptr->U.I.DstReg.File == RC_FILE_TEMPORARY &&
							    ptr->U.I.DstReg.WriteMask) {
								mark_used(&s,
									  ptr->U.I.DstReg.File,
									  ptr->U.I.DstReg.Index,
									  ptr->U.I.DstReg.WriteMask);
							}
						}

						has_temp_reladdr_src = 1;
						break;
					}
				}
			}
		}

		update_instruction(&s, inst);
	}

	unsigned int ip = 0;
	for(struct rc_instruction * inst = c->Program.Instructions.Next;
	    inst != &c->Program.Instructions;
	    inst = inst->Next, ++ip) {
		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
		int dead = 1;

		if (!opcode->HasDstReg) {
			dead = 0;
		} else {
			inst->U.I.DstReg.WriteMask = s.Instructions[ip].WriteMask;
			if (s.Instructions[ip].WriteMask)
				dead = 0;

			if (s.Instructions[ip].WriteALUResult)
				dead = 0;
			else
				inst->U.I.WriteALUResult = RC_ALURESULT_NONE;
		}

		if (dead) {
			struct rc_instruction * todelete = inst;
			inst = inst->Prev;
			rc_remove_instruction(todelete);
			continue;
		}

		unsigned int srcmasks[3];
		unsigned int usemask = s.Instructions[ip].WriteMask;

		if (inst->U.I.WriteALUResult == RC_ALURESULT_X)
			usemask |= RC_MASK_X;
		else if (inst->U.I.WriteALUResult == RC_ALURESULT_W)
			usemask |= RC_MASK_W;

		rc_compute_sources_for_writemask(inst, usemask, srcmasks);

		for(unsigned int src = 0; src < 3; ++src) {
			for(unsigned int chan = 0; chan < 4; ++chan) {
				if (!GET_BIT(srcmasks[src], chan))
					SET_SWZ(inst->U.I.SrcReg[src].Swizzle, chan, RC_SWIZZLE_UNUSED);
			}
		}
	}

	rc_calculate_inputs_outputs(c);
}


text:
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK

./matrix_mult


text:
var tape = require('tape')
var ssbref = require('ssb-ref')
var mlib = require('ssb-msgs')

var input = require('./input')
var output = require('./output')
var outputInline = require('./output-inline')
var markdown = require('../')

var tests = [
  'message with link',
  'message with image',
  'message with "@" mentions',
  'message with emoji',
  'message with ascii emoji',
  'message with inline html in code block',
  'message with hashtag',
  'message with customs protocols',
  'message with links, mentions, headers, and code',
  'message with both emoji and :shortcodes:',
  'message with compound emoji',
  'message with node-emoji shortcodes',
  'message with sigil links in proper Markdown',
  'message with non-ASCII unicode hashtag',
  'message with external image',
  'message with private image',
  'message with %70 link'
]

// behavior expected by current tests
var emoji = (emoji) => `<span class="emoji">${emoji}</span>`

// run tests over input and output for current defaults.
tests.forEach(function (e, i) {
  tape(e, function (t) {
    // extract mention names
    var mentionNames = {}
    mlib.links(input[i].content.mentions, 'feed').forEach(function (link) {
      if (link.name && typeof link.name === 'string') {
        var name = (link.name.charAt(0) === '@') ? link.name : '@' + link.name
        mentionNames[name] = link.link
      }
    })
    var toUrl = function (ref, isImage) {
      // @-mentions
      if (ref in mentionNames) {
        return '#/profile/' + encodeURIComponent(mentionNames[ref])
      }

      const link = ssbref.parseLink(ref)

      // standard ssb-refs
      if (ssbref.isFeedId(ref)) {
        return '#/profile/' + encodeURIComponent(ref)
      } else if (ssbref.isMsgId(ref)) {
        return '#/msg/' + encodeURIComponent(ref)
      } else if (ssbref.isBlobId(link ? link.link : ref)) {
        return '/' + encodeURIComponent(ref)
      } else if (ref && ref[0] === '#') {
        return '#/channel/' + ref.substr(1)
      }
      return ''
    }

    var imageLink = function (ref) {
      return '#' + ref
    }

    t.equal(
      markdown.block(input[i].content.text, {
        toUrl: toUrl,
        imageLink: imageLink,
        emoji
      }),
      output[i]
    )
    t.end()
  })
  tape(e, function (t) {
    t.equal(
      markdown.inline(input[i].content.text, {
        emoji
      }),
      outputInline[i]
    )
    t.end()
  })
})


text:
require "spec_helper"
require "hotdog/application"
require "hotdog/commands"
require "hotdog/commands/search"
require "parslet"

describe "tag regexp expression" do
  let(:cmd) {
    Hotdog::Commands::Search.new(Hotdog::Application.new)
  }

  before(:each) do
    ENV["DATADOG_API_KEY"] = "DATADOG_API_KEY"
    ENV["DATADOG_APPLICATION_KEY"] = "DATADOG_APPLICATION_KEY"
  end

  it "interprets tag regexp with host" do
    expr = Hotdog::Expression::RegexpHostNode.new("foo", ":")
    q = [
      "SELECT hosts.id AS host_id FROM hosts",
        "WHERE hosts.name REGEXP ?;",
    ]
    allow(cmd).to receive(:execute).with(q.join(" "), ["foo"]) {
      [[1], [2], [3]]
    }
    expect(expr.evaluate(cmd)).to eq([1, 2, 3])
    expect(expr.dump).to eq({tagname_regexp: "@host", separator: ":", tagvalue_regexp: "foo"})
  end

  it "interprets tag regexp with tagname and tagvalue" do
    expr = Hotdog::Expression::RegexpTagNode.new("foo", "bar", ":")
    q = [
      "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
        "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
          "WHERE tags.name REGEXP ? AND tags.value REGEXP ?;",
    ]
    allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "bar"]) {
      [[1], [2], [3]]
    }
    expect(expr.evaluate(cmd)).to eq([1, 2, 3])
    expect(expr.dump).to eq({tagname_regexp: "foo", separator: ":", tagvalue_regexp: "bar"})
  end

  it "interprets tag regexp with tagname with separator" do
    expr = Hotdog::Expression::RegexpTagnameNode.new("foo", ":")
    q = [
      "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
        "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
          "WHERE tags.name REGEXP ?;",
    ]
    allow(cmd).to receive(:execute).with(q.join(" "), ["foo"]) {
      [[1], [2], [3]]
    }
    expect(expr.evaluate(cmd)).to eq([1, 2, 3])
    expect(expr.dump).to eq({tagname_regexp: "foo", separator: ":"})
  end

  it "interprets tag regexp with tagname without separator" do
    expr = Hotdog::Expression::RegexpHostOrTagNode.new("foo", nil)
    q = [
      "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
        "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
        "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
          "WHERE hosts.name REGEXP ? OR tags.name REGEXP ? OR tags.value REGEXP ?;",
    ]
    allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo", "foo"]) {
      [[1], [2], [3]]
    }
    expect(expr.evaluate(cmd)).to eq([1, 2, 3])
    expect(expr.dump).to eq({tagname_regexp: "foo"})
  end

  it "interprets tag regexp with tagvalue with separator" do
    expr = Hotdog::Expression::RegexpTagvalueNode.new("foo", ":")
    q = [
      "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
        "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
        "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
          "WHERE hosts.name REGEXP ? OR tags.value REGEXP ?;",
    ]
    allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo"]) {
      [[1], [2], [3]]
    }
    expect(expr.evaluate(cmd)).to eq([1, 2, 3])
    expect(expr.dump).to eq({separator: ":", tagvalue_regexp: "foo"})
  end

  it "interprets tag regexp with tagvalue without separator" do
    expr = Hotdog::Expression::RegexpTagvalueNode.new("foo", nil)
    q = [
      "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
        "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
        "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
          "WHERE hosts.name REGEXP ? OR tags.value REGEXP ?;",
    ]
    allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo"]) {
      [[1], [2], [3]]
    }
    expect(expr.evaluate(cmd)).to eq([1, 2, 3])
    expect(expr.dump).to eq({tagvalue_regexp: "foo"})
  end

  it "empty tag regexp" do
    expr = Hotdog::Expression::RegexpExpressionNode.new(nil, nil, nil)
    expect {
      expr.evaluate(cmd)
    }.to raise_error(NotImplementedError)
    expect(expr.dump).to eq({})
  end
end


text:
using System.Collections.Generic;
using OrchardVNext.Mvc.Routes;

namespace OrchardVNext.Demo {
    public class Routes : IRouteProvider {
        public IEnumerable<RouteDescriptor> GetRoutes() {
            return new[] {
                new RouteDescriptor {
                    Route = new Route(
                        null,
                        "Home/Index",
                        defaults:  new
                            {
                                area = "OrchardVNext.Demo",
                                controller = "Home",
                                action = "Index"
                            },
                        dataTokens:  new
                            {
                                area = "OrchardVNext.Demo"
                            }
                        )

                }
            };
        }
    }
}


text:
namespace SoftwareAcademyAndShit
{
    public interface ITeacher
    {
        string Name { get; set; }
        void AddCourse(ICourse course);
        string ToString();

    }
}


text:
layout: post
title:  "VMWare Lab Manager and Perl"
date:   2009-12-08 21:46:00
categories: vmware vm labmanager
---

VMware's Lab Manager is an amazing tool to have for testing organizations (which was originally designed by a company called Akimbi). But this post is not about what it is & how it can be useful. This post is to give you an example on  how you can consume its SOAP API from Perl. We use Lab Manager extensively for all our feature testing & automation. For automation, you can deploy, undeploy and change some of the vm properties using the SOAP API. Lab Manager also has more "[internal API][internal-api]", which is not officially supported but can be used for more control of what kind of automation you wanna do.

Anyhoo, for my group I ended up creating a simple perl module to deploy & undeploy (and delete) library configurations. For SOAP, I used SOAP::Lite, which is very widely used & supported module. The attached module is a working example. Just remember that each request to the LM server requires that you send auth headers (read the LM API documentation for further info). get_auth_header accomplishes that in my module.

The module has its own POD to help you out. If you optimize it & add more methods to it, please let me know.

Project page: [VMware-LabManager][lm]

[internal-api]: https://communities.vmware.com/community/vmtn/vcenter/labmanager/content?filterID=contentstatus[published]~objecttype~objecttype[document]
[lm]: https://github.com/aivaturi/VMware-LabManager


text:
package net.kuujo.copycat.io.storage;

import net.kuujo.copycat.io.Buffer;
import net.kuujo.copycat.io.FileBuffer;
import net.kuujo.copycat.io.HeapBuffer;
import net.kuujo.copycat.util.Assert;

/**
 * Segment descriptor.
 *

 * The segment descriptor manages metadata related to a single segment of the log. Descriptors are stored within the
 * first {@code 48} bytes of each segment in the following order:
 * - {@code id} (64-bit signed integer) - A unique segment identifier. This is a monotonically increasing number within
 *   each log. Segments with in-sequence identifiers should contain in-sequence indexes.
 * - {@code index} (64-bit signed integer) - The effective first index of the segment. This indicates the index at which
 *   the first entry should be written to the segment. Indexes are monotonically increasing thereafter.
 * - {@code range} (64-bit signed integer) - The effective length of the segment. Regardless of the actual number of
 *   entries in the segment, the range indicates the total number of allowed entries within each segment. If a segment's
 *   index is {@code 1} and its range is {@code 10} then the next segment should start at index {@code 11}.
 * - {@code version} (64-bit signed integer) - The version of the segment. Versions are monotonically increasing
 *   starting at {@code 1}. Versions will only be incremented whenever the segment is rewritten to another memory/disk
 *   space, e.g. after log compaction.
 * - {@code updated} (64-bit signed integer) - The last update to the segment in terms of milliseconds since the epoch.
 *   When the segment is first constructed, the {@code updated} time is {@code 0}. Once all entries in the segment have
 *   been committed, the {@code updated} time should be set to the current time. Log compaction should not result in a
 *   change to {@code updated}.
 * - {@code maxEntrySize} (32-bit signed integer) - The maximum length in bytes of entry values allowed by the segment.
 * - {@code entries} (32-bit signed integer) - The total number of expected entries in the segment. This is the final
 *   number of entries allowed within the segment both before and after compaction. This entry count is used to determine
 *   the count of internal indexing and deduplication facilities.
 * - {@code locked} (8-bit boolean) - A boolean indicating whether the segment is locked. Segments will be locked once
 *   all entries have been committed to the segment. The lock state of each segment is used to determine log compaction
 *   and recovery behavior.
 *
 * @author Jordan Halterman
 */
final class SegmentDescriptor implements AutoCloseable {
  public static final int BYTES = 52;

  /**
   * Returns a descriptor builder.
   *

   * The descriptor builder will write segment metadata to a {@code 48} byte in-memory buffer.
   *
   * @return The descriptor builder.
   */
  public static Builder builder() {
    return new Builder(HeapBuffer.allocate(BYTES));
  }

  /**
   * Returns a descriptor builder for the given descriptor buffer.
   *
   * @param buffer The descriptor buffer.
   * @return The descriptor builder.
   * @throws NullPointerException if {@code buffer} is null
   */
  public static Builder builder(Buffer buffer) {
    return new Builder(buffer);
  }

  private Buffer buffer;
  private final long id;
  private final long index;
  private final long version;
  private long updated;
  private final int maxEntrySize;
  private final long maxSegmentSize;
  private final int maxEntries;
  private boolean locked;

  /**
   * @throws NullPointerException if {@code buffer} is null
   */
  public SegmentDescriptor(Buffer buffer) {
    this.buffer = Assert.notNull(buffer, "buffer");
    this.id = buffer.readLong();
    this.version = buffer.readLong();
    this.index = buffer.readLong();
    this.maxEntrySize = buffer.readUnsignedMedium();
    this.maxSegmentSize = buffer.readUnsignedInt();
    this.maxEntries = buffer.readInt();
    this.updated = buffer.readLong();
    this.locked = buffer.readBoolean();
  }

  /**
   * Returns the segment identifier.
   *

   * The segment ID is a monotonically increasing number within each log. Segments with in-sequence identifiers should
   * contain in-sequence indexes.
   *
   * @return The segment identifier.
   */
  public long id() {
    return id;
  }

  /**
   * Returns the segment version.
   *

   * Versions are monotonically increasing starting at {@code 1}. Versions will only be incremented whenever the segment
   * is rewritten to another memory/disk space, e.g. after log compaction.
   *
   * @return The segment version.
   */
  public long version() {
    return version;
  }

  /**
   * Returns the segment index.
   *

   * The index indicates the index at which the first entry should be written to the segment. Indexes are monotonically
   * increasing thereafter.
   *
   * @return The segment index.
   */
  public long index() {
    return index;
  }

  /**
   * Returns the maximum entry count for the segment.
   *
   * @return The maximum number of bytes for each entry in the segment.
   */
  public int maxEntrySize() {
    return maxEntrySize;
  }

  /**
   * Returns the maximum count of the segment.
   *
   * @return The maximum allowed count of the segment.
   */
  public long maxSegmentSize() {
    return maxSegmentSize;
  }

  /**
   * Returns the maximum number of entries allowed in the segment.
   *
   * @return The maximum number of entries allowed in the segment.
   */
  public int maxEntries() {
    return maxEntries;
  }

  /**
   * Returns last time the segment was updated.
   *

   * When the segment is first constructed, the {@code updated} time is {@code 0}. Once all entries in the segment have
   * been committed, the {@code updated} time should be set to the current time. Log compaction should not result in a
   * change to {@code updated}.
   *
   * @return The last time the segment was updated in terms of milliseconds since the epoch.
   */
  public long updated() {
    return updated;
  }

  /**
   * Writes an update to the descriptor.
   */
  void update(long timestamp) {
    if (!locked) {
      buffer.writeLong(35, timestamp);
      this.updated = timestamp;
    }
  }

  /**
   * Returns whether the segment has been locked by commitment.
   *

   * Segments will be locked once all entries have been committed to the segment. The lock state of each segment is used
   * to determine log compaction and recovery behavior.
   *
   * @return Indicates whether the segment has been locked.
   */
  public boolean locked() {
    return locked;
  }

  /**
   * Locks the segment.
   */
  void lock() {
    buffer.writeBoolean(43, true).flush();
    locked = true;
  }

  /**
   * Copies the segment to a new buffer.
   */
  SegmentDescriptor copyTo(Buffer buffer) {
    this.buffer = buffer
      .writeLong(id)
      .writeLong(version)
      .writeLong(index)
      .writeUnsignedMedium(maxEntrySize)
      .writeUnsignedInt(maxSegmentSize)
      .writeInt(maxEntries)
      .writeLong(updated)
      .writeBoolean(locked)
      .flush();
    return this;
  }

  @Override
  public void close() {
    buffer.close();
  }

  /**
   * Deletes the descriptor.
   */
  public void delete() {
    if (buffer instanceof FileBuffer)
      ((FileBuffer) buffer).delete();
  }

  /**
   * Segment descriptor builder.
   */
  public static class Builder {
    private final Buffer buffer;

    private Builder(Buffer buffer) {
      this.buffer = Assert.notNull(buffer, "buffer");
    }

    /**
     * Sets the segment identifier.
     *
     * @param id The segment identifier.
     * @return The segment descriptor builder.
     */
    public Builder withId(long id) {
      buffer.writeLong(0, id);
      return this;
    }

    /**
     * Sets the segment version.
     *
     * @param version The segment version.
     * @return The segment descriptor builder.
     */
    public Builder withVersion(long version) {
      buffer.writeLong(8, version);
      return this;
    }

    /**
     * Sets the segment index.
     *
     * @param index The segment starting index.
     * @return The segment descriptor builder.
     */
    public Builder withIndex(long index) {
      buffer.writeLong(16, index);
      return this;
    }

    /**
     * Sets the maximum entry count for the segment.
     *
     * @param maxEntrySize The maximum entry count for the segment.
     * @return The segment descriptor builder.
     */
    public Builder withMaxEntrySize(int maxEntrySize) {
      buffer.writeUnsignedMedium(24, maxEntrySize);
      return this;
    }

    /**
     * Sets maximum count of the segment.
     *
     * @param maxSegmentSize The maximum count of the segment.
     * @return The segment descriptor builder.
     */
    public Builder withMaxSegmentSize(long maxSegmentSize) {
      buffer.writeUnsignedInt(27, maxSegmentSize);
      return this;
    }

    /**
     * Sets the maximum number of entries in the segment.
     *
     * @param maxEntries The maximum number of entries in the segment.
     * @return The segment descriptor builder.
     */
    public Builder withMaxEntries(int maxEntries) {
      buffer.writeInt(31, maxEntries);
      return this;
    }

    /**
     * Builds the segment descriptor.
     *
     * @return The built segment descriptor.
     */
    public SegmentDescriptor build() {
      return new SegmentDescriptor(buffer.writeLong(43, 0).rewind());
    }

  }

}


text:
#ifndef __SCRIPT_H_
#define __SCRIPT_H_

/*
 * Script.c unit provides an API for functions and eval
 * to interact with Redis. Interaction includes mostly
 * executing commands, but also functionalities like calling
 * Redis back on long scripts or check if the script was killed.
 *
 * The interaction is done using a scriptRunCtx object that
 * need to be created by the user and initialized using scriptPrepareForRun.
 *
 * Detailed list of functionalities expose by the unit:
 * 1. Calling commands (including all the validation checks such as
 *    acl, cluster, read only run, ...)
 * 2. Set Resp
 * 3. Set Replication method (AOF/REPLICATION/NONE)
 * 4. Call Redis back to on long running scripts to allow Redis reply
 *    to clients and perform script kill
 */

/*
 * scriptInterrupt function will return one of those value,
 *
 * - SCRIPT_KILL - kill the current running script.
 * - SCRIPT_CONTINUE - keep running the current script.
 */
#define SCRIPT_KILL 1
#define SCRIPT_CONTINUE 2

/* runCtx flags */
#define SCRIPT_WRITE_DIRTY            (1ULL<<0) /* indicate that the current script already performed a write command */
#define SCRIPT_TIMEDOUT               (1ULL<<3) /* indicate that the current script timedout */
#define SCRIPT_KILLED                 (1ULL<<4) /* indicate that the current script was marked to be killed */
#define SCRIPT_READ_ONLY              (1ULL<<5) /* indicate that the current script should only perform read commands */
#define SCRIPT_ALLOW_OOM              (1ULL<<6) /* indicate to allow any command even if OOM reached */
#define SCRIPT_EVAL_MODE              (1ULL<<7) /* Indicate that the current script called from legacy Lua */
typedef struct scriptRunCtx scriptRunCtx;

struct scriptRunCtx {
    const char *funcname;
    client *c;
    client *original_client;
    int flags;
    int repl_flags;
    monotime start_time;
    mstime_t snapshot_time;
};

/* Scripts flags */
#define SCRIPT_FLAG_NO_WRITES        (1ULL<<0)
#define SCRIPT_FLAG_ALLOW_OOM        (1ULL<<1)
#define SCRIPT_FLAG_ALLOW_STALE      (1ULL<<2)
#define SCRIPT_FLAG_NO_CLUSTER       (1ULL<<3)
#define SCRIPT_FLAG_EVAL_COMPAT_MODE (1ULL<<4) /* EVAL Script backwards compatible behavior, no shebang provided */

/* Defines a script flags */
typedef struct scriptFlag {
    uint64_t flag;
    const char *str;
} scriptFlag;

extern scriptFlag scripts_flags_def[];

int scriptPrepareForRun(scriptRunCtx *r_ctx, client *engine_client, client *caller, const char *funcname, uint64_t script_flags, int ro);
void scriptResetRun(scriptRunCtx *r_ctx);
int scriptSetResp(scriptRunCtx *r_ctx, int resp);
int scriptSetRepl(scriptRunCtx *r_ctx, int repl);
void scriptCall(scriptRunCtx *r_ctx, robj **argv, int argc, sds *err);
int scriptInterrupt(scriptRunCtx *r_ctx);
void scriptKill(client *c, int is_eval);
int scriptIsRunning();
const char* scriptCurrFunction();
int scriptIsEval();
int scriptIsTimedout();
client* scriptGetClient();
client* scriptGetCaller();
mstime_t scriptTimeSnapshot();
long long scriptRunDuration();

#endif /* __SCRIPT_H_ */


text:
from tempest.common import cred_provider
from tempest import config
from tempest import exceptions
from tempest.lib import auth

CONF = config.CONF

class Manager(object):
    """Base manager class

    Manager objects are responsible for providing a configuration object
    and a client object for a test case to use in performing actions.
    """

    def __init__(self, credentials):
        """Initialization of base manager class

        Credentials to be used within the various client classes managed by the
        Manager object must be defined.

        :param credentials: type Credentials or TestResources
        """
        self.credentials = credentials
        # Check if passed or default credentials are valid
        if not self.credentials.is_valid():
            raise exceptions.InvalidCredentials()
        self.auth_version = CONF.identity.auth_version
        # Tenant isolation creates TestResources, but
        # PreProvisionedCredentialProvider and some tests create Credentials
        if isinstance(credentials, cred_provider.TestResources):
            creds = self.credentials.credentials
        else:
            creds = self.credentials
        # Creates an auth provider for the credentials
        self.auth_provider = get_auth_provider(creds, pre_auth=True)

def get_auth_provider_class(credentials):
    if isinstance(credentials, auth.KeystoneV3Credentials):
        return auth.KeystoneV3AuthProvider, CONF.identity.uri_v3
    else:
        return auth.KeystoneV2AuthProvider, CONF.identity.uri

def get_auth_provider(credentials, pre_auth=False):
    default_params = {
        'disable_ssl_certificate_validation':
            CONF.identity.disable_ssl_certificate_validation,
        'ca_certs': CONF.identity.ca_certificates_file,
        'trace_requests': CONF.debug.trace_requests
    }
    if credentials is None:
        raise exceptions.InvalidCredentials(
            'Credentials must be specified')
    auth_provider_class, auth_url = get_auth_provider_class(
        credentials)
    _auth_provider = auth_provider_class(credentials, auth_url,
                                         **default_params)
    if pre_auth:
        _auth_provider.set_auth()
    return _auth_provider


text:
<?php

namespace Acme\Task5Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Acme\DemoBundle\Form\ContactType;

// these import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DefaultController extends Controller
{
    public function indexAction()
    {
        return $this->render('AcmeTask5Bundle:Default:index.html.twig',
            array(
                'page_name'=>'index',
                'tent_name'=>'Imogene UL2 Tent',
                'price'=>'$249.99',
                'description'=>'Our lightest weight free-standing tent ever. Roomy enough for two, light enough for one.
                Setting the standard for ultra-lightweight livable space. 2013 Backpacker Magazine Gear Guide Pick for
                 Best Freestanding Ultralight Tent.',
            )
        );
    }

    public function aboutAction()
    {
        return $this->render('AcmeTask5Bundle:Default:about.html.twig',
            array(
                'page_name'=>'about',
                'description'=>'Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus
                commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem
                malesuada magna mollis euismod. Donec sed odio dui.',
            )
        );
    }

    public function contactAction()
    {
        return $this->render('AcmeTask5Bundle:Default:contact.html.twig',
            array(
                'page_name'=>'contact',
                'description'=>'Cras vulputate in felis at egestas. Mauris ut diam risus. Sed in dapibus sapien.
                Vestibulum viverra ut ligula in mattis. Proin in lacus pellentesque, tincidunt sem id, gravida urna.
                Donec lacus risus, imperdiet a purus non, tristique aliquam leo. Nam nec tincidunt sem, eu pulvinar
                erat. Nulla sed risus eu est blandit iaculis eget vel eros.'
            )
        );
    }
}


text: sudo apt-get install --only-upgrade unzip=6.0-13ubuntu3.2 -y


text:
using UnityEngine;

namespace Microsoft.MixedReality.Toolkit.Utilities.Solvers
{
    /// <summary>
    /// Provides a solver that follows the TrackedObject/TargetTransform in an orbital motion.
    /// </summary>
    public class Orbital : Solver
    {
        [SerializeField]
        [Tooltip("The desired orientation of this object. Default sets the object to face the TrackedObject/TargetTransform. CameraFacing sets the object to always face the user.")]
        private SolverOrientationType orientationType = SolverOrientationType.FollowTrackedObject;

        /// <summary>
        /// The desired orientation of this object.
        /// </summary>
        /// <remarks>
        /// Default sets the object to face the TrackedObject/TargetTransform. CameraFacing sets the object to always face the user.
        /// </remarks>
        public SolverOrientationType OrientationType
        {
            get { return orientationType; }
            set { orientationType = value; }
        }

        [SerializeField]
        [Tooltip("XYZ offset for this object in relation to the TrackedObject/TargetTransform. Mixing local and world offsets is not recommended.")]
        private Vector3 localOffset = new Vector3(0, -1, 1);

        /// <summary>
        /// XYZ offset for this object in relation to the TrackedObject/TargetTransform.
        /// </summary>
        /// <remarks>
        /// Mixing local and world offsets is not recommended.
        /// </remarks>
        public Vector3 LocalOffset
        {
            get { return localOffset; }
            set { localOffset = value; }
        }

        [SerializeField]
        [Tooltip("XYZ offset for this object in worldspace, best used with the YawOnly orientationType. Mixing local and world offsets is not recommended.")]
        private Vector3 worldOffset = Vector3.zero;

        /// <summary>
        /// XYZ offset for this object in worldspace, best used with the YawOnly orientationType.
        /// </summary>
        /// <remarks>
        /// Mixing local and world offsets is not recommended.
        /// </remarks>
        public Vector3 WorldOffset
        {
            get { return worldOffset; }
            set { worldOffset = value; }
        }

        [SerializeField]
        [Tooltip("Lock the rotation to a specified number of steps around the tracked object.")]
        private bool useAngleSteppingForWorldOffset = false;

        /// <summary>
        /// Lock the rotation to a specified number of steps around the tracked object.
        /// </summary>
        public bool UseAngleSteppingForWorldOffset
        {
            get { return useAngleSteppingForWorldOffset; }
            set { useAngleSteppingForWorldOffset = value; }
        }

        [Range(2, 24)]
        [SerializeField]
        [Tooltip("The division of steps this object can tether to. Higher the number, the more snapple steps.")]
        private int tetherAngleSteps = 6;

        /// <summary>
        /// The division of steps this object can tether to. Higher the number, the more snapple steps.
        /// </summary>
        public int TetherAngleSteps
        {
            get { return tetherAngleSteps; }
            set
            {
                tetherAngleSteps =  Mathf.Clamp(value, 2, 24);
            }
        }

        public override void SolverUpdate()
        {
            Vector3 desiredPos = SolverHandler.TransformTarget != null ? SolverHandler.TransformTarget.position : Vector3.zero;

            Quaternion targetRot = SolverHandler.TransformTarget != null ? SolverHandler.TransformTarget.rotation : Quaternion.Euler(0, 1, 0);
            Quaternion yawOnlyRot = Quaternion.Euler(0, targetRot.eulerAngles.y, 0);
            desiredPos = desiredPos + (SnapToTetherAngleSteps(targetRot) * LocalOffset);
            desiredPos = desiredPos + (SnapToTetherAngleSteps(yawOnlyRot) * WorldOffset);

            Quaternion desiredRot = CalculateDesiredRotation(desiredPos);

            GoalPosition = desiredPos;
            GoalRotation = desiredRot;

            UpdateWorkingPositionToGoal();
            UpdateWorkingRotationToGoal();
        }

        private Quaternion SnapToTetherAngleSteps(Quaternion rotationToSnap)
        {
            if (!UseAngleSteppingForWorldOffset || SolverHandler.TransformTarget == null)
            {
                return rotationToSnap;
            }

            float stepAngle = 360f / tetherAngleSteps;
            int numberOfSteps = Mathf.RoundToInt(SolverHandler.TransformTarget.transform.eulerAngles.y / stepAngle);

            float newAngle = stepAngle * numberOfSteps;

            return Quaternion.Euler(rotationToSnap.eulerAngles.x, newAngle, rotationToSnap.eulerAngles.z);
        }

        private Quaternion CalculateDesiredRotation(Vector3 desiredPos)
        {
            Quaternion desiredRot = Quaternion.identity;

            switch (orientationType)
            {
                case SolverOrientationType.YawOnly:
                    float targetYRotation = SolverHandler.TransformTarget != null ? SolverHandler.TransformTarget.eulerAngles.y : 0.0f;
                    desiredRot = Quaternion.Euler(0f, targetYRotation, 0f);
                    break;
                case SolverOrientationType.Unmodified:
                    desiredRot = transform.rotation;
                    break;
                case SolverOrientationType.CameraAligned:
                    desiredRot = CameraCache.Main.transform.rotation;
                    break;
                case SolverOrientationType.FaceTrackedObject:
                    desiredRot = SolverHandler.TransformTarget != null ? Quaternion.LookRotation(SolverHandler.TransformTarget.position - desiredPos) : Quaternion.identity;
                    break;
                case SolverOrientationType.CameraFacing:
                    desiredRot = SolverHandler.TransformTarget != null ? Quaternion.LookRotation(CameraCache.Main.transform.position - desiredPos) : Quaternion.identity;
                    break;
                case SolverOrientationType.FollowTrackedObject:
                    desiredRot = SolverHandler.TransformTarget != null ? SolverHandler.TransformTarget.rotation : Quaternion.identity;
                    break;
                default:
                    Debug.LogError($"Invalid OrientationType for Orbital Solver on {gameObject.name}");
                    break;
            }

            if (UseAngleSteppingForWorldOffset)
            {
                desiredRot = SnapToTetherAngleSteps(desiredRot);
            }

            return desiredRot;
        }
    }
}


text:
<?xml version="1.0" encoding="ascii"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "DTD/xhtml1-transitional.dtd">

  <title>cocos.camera</title>
  <link rel="stylesheet" href="epydoc.css" type="text/css" />

      Trees

      Indices

          cocos . camera

        Toggle frames

Module cocos.camera

Camera object

Classes

        Camera

Camera used in every CocosNode.

      Trees

      Indices

          cocos . camera

        Toggle frames

    Generated by Epydoc 3.0beta1 on Sun Aug 12 20:39:17 2012

      http://epydoc.sourceforge.net


text:
'use strict';

const moment = require('moment');

const searchForOpenMicNights = require('../../../../../utils/searchForOpenMicNights');
const url = 'http://www.hardtailsbarandgrill.com/';
const Venue = require('../../../../../app/models/venue');

function hardtailsBarAndGrill($) {
  const events = (venue) => {
    searchForOpenMicNights('Tuesday nights from 7pm to 10pm', $, 'p');
    searchForOpenMicNights('Wednesdays starts at 8pm', $, 'p');

    return [
      {
        frequency: 'weekly',
        startDate: moment().isoWeekday(2).format('MM-DD-YYYY'),
        startTime: '7pm to 10pm',
        title: 'Open Mic Night',
        venue: venue._id
      },
      {
        frequency: 'weekly',
        startDate: moment().isoWeekday(3).format('MM-DD-YYYY'),
        startTime: '8pm',
        title: 'Karaoke',
        venue: venue._id
      }
    ];
  };

  return Venue
    .findOne({ name: 'Hardtails Bar and Grill', city: 'Georgetown' })
    .then((venue) => events(venue));
}

module.exports = {
  run: hardtailsBarAndGrill,
  url
};