swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.94k stars 6.03k forks source link

[develop_2.0] Does swagger codegen 2.1 generates OAuth2 dedicated methods ? #347

Closed sovannaN closed 9 years ago

sovannaN commented 9 years ago

I see in swagger 2.0 spec that security schemes such as OAuth2 are available. In the petstore.json file from the develop_2.0 branche, oauth2 is defined in the "securityDefinitions" part but I don't see any dedicated method in android-java client code generated. I thought I would have found a method calling the authorizationUrl defined below in one of the generated classes :
"petstore_auth": { "type": "oauth2", "authorizationUrl": "http://petstore.swagger.wordnik.com/api/oauth/dialog", "flow": "implicit" }

fehguy commented 9 years ago

Your observation is correct. While the swagger-spec supports the authorization information, the codegen and clients do not yet. There are three reasons:

1) The codegen is not complete yet. I expect to have all mechanisms for the authorization in it before release 2) Introducing support into each client framework / library is beyond our capabilities alone, we need support from the community (which the community has been very generous to help with historically) 3) Adding support in each client will force a specific dependency / workflow. For instance, the android client may be for a web-based app in a native wrapper, or for a fully native app. The client interaction for authorization will be extremely different depending on this. Same goes for all other languages

That said, I DO want to get android + oauth2 support directly in that client library, if nothing else as a demonstration or specific implementation. If you want to point to some mature, OSS oauth SDK for android I'd be happy to use it as a prototype.

fehguy commented 9 years ago

The codegen should have the oauth2 info in the data for the templates.

cbornet commented 9 years ago

Hello,

:+1: to have the oauth2 data available for the templates. I did the following in my project to have it: CodegenSecurity.java

public class CodegenSecurity {
    public String name;
    public String type;
    public Boolean hasMore, isBasic, isOAuth, isApiKey;
    // ApiKey specific
    public String keyParamName;
    public Boolean isKeyInQuery, isKeyInHeader;
    // Oauth specific
    public String flow, authorizationUrl, tokenUrl;
    public Set<String> scopes;
}

DefaultGenerator.java

SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);

                    if (securityDefinition != null) {
                        if(securityDefinition instanceof OAuth2Definition) {
                            OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
                            OAuth2Definition oauth2Operation = new OAuth2Definition();
                            oauth2Operation.setType(oauth2Definition.getType());
                            oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
                            oauth2Operation.setFlow(oauth2Definition.getFlow());
                            oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
                            for (String scope : security.values().iterator().next()) {
                                if (oauth2Definition.getScopes().containsKey(scope)) {
                                    oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
                                }
                            }
                            authMethods.put(securityName, oauth2Operation);
                        } else {
                            authMethods.put(securityName, securityDefinition);  
                        }
                    }

DefaultCodegen.java

if (schemeDefinition instanceof ApiKeyAuthDefinition) {
                final ApiKeyAuthDefinition apiKeyDefinition = (ApiKeyAuthDefinition) schemeDefinition;
                sec.isBasic = sec.isOAuth = false;
                sec.isApiKey = true;
                sec.keyParamName = apiKeyDefinition.getName();
                sec.isKeyInHeader = apiKeyDefinition.getIn() == In.HEADER;
                sec.isKeyInQuery = !sec.isKeyInHeader;
            } else if(schemeDefinition instanceof BasicAuthDefinition) {
                sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isOAuth = false;
                sec.isBasic = true;
            } else {
                final OAuth2Definition oauth2Definition = (OAuth2Definition) schemeDefinition;
                sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false;
                sec.isOAuth = true;
                sec.flow = oauth2Definition.getFlow();
                sec.authorizationUrl = oauth2Definition.getAuthorizationUrl();
                sec.tokenUrl = oauth2Definition.getTokenUrl();
                sec.scopes = oauth2Definition.getScopes().keySet();
            }

With this you can for instance get the operation scopes in the template with:

String[] scopes = new String[] { {{#authMethods}}{{#scopes}}{{^-first}}, {{/-first}}"{{this}}"{{/scopes}}{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
wing328 commented 9 years ago

@cbornet :+1:

Thanks for your work on supporting OAuth in Swagger Codegen project. Do you mind submitting a PR for develop_2.0 branch ? Let me know if you need any on that.