go-swagger: Swager generate panic - commit #e2bfe4232707b33df6e46519f71f5d22cc6bf63b

Environment

swagger version: commit #e2bfe4232707b33df6e46519f71f5d22cc6bf63b go version: 1.8.3 OS: OSX

swagger generate server ./swagger.yaml

2017/09/02 11:55:07 building a plan for generation
2017/09/02 11:55:07 planning definitions
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0xd pc=0x1567009]

goroutine 1 [running]:
github.com/go-swagger/go-swagger/generator.(*schemaGenContext).NewSliceBranch(0xc421c22000, 0xc421b88fc0, 0x1)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:387 +0x529
github.com/go-swagger/go-swagger/generator.(*schemaGenContext).buildArray(0xc421c22000, 0x0, 0x0)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:1068 +0xe2
github.com/go-swagger/go-swagger/generator.(*schemaGenContext).buildItems(0xc421c22000, 0x0, 0x0)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:1104 +0xc57
github.com/go-swagger/go-swagger/generator.(*schemaGenContext).makeGenSchema(0xc421c22000, 0xc4210ac22c, 0x4)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:1445 +0xabc
github.com/go-swagger/go-swagger/generator.(*schemaGenContext).buildProperties(0xc420155200, 0xc4201552a8, 0x100)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:660 +0x304
github.com/go-swagger/go-swagger/generator.(*schemaGenContext).makeGenSchema(0xc420155200, 0x0, 0xc421f0bc50)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:1433 +0x9f3
github.com/go-swagger/go-swagger/generator.makeGenDefinitionHierarchy(0xc4210c4e80, 0x7, 0xc421c9cf78, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:166 +0x32c
github.com/go-swagger/go-swagger/generator.makeGenDefinition(0xc4210c4e80, 0x7, 0xc421c9cf78, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/model.go:133 +0xbc
github.com/go-swagger/go-swagger/generator.(*appGenerator).makeCodegenApp(0xc42001e690, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/support.go:610 +0x5d9
github.com/go-swagger/go-swagger/generator.(*appGenerator).Generate(0xc42001e690, 0x0, 0x0)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/support.go:262 +0x94
github.com/go-swagger/go-swagger/generator.GenerateServer(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4203a85a0, 0xc4206ef4b0, ...)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/generator/support.go:43 +0xcb
github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.(*Server).Execute(0xc420870840, 0xc4208678c0, 0x1, 0x3, 0xc420870840, 0x1)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go:118 +0x54a
github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags.(*Parser).ParseArgs(0xc42001c960, 0xc420010250, 0x3, 0x3, 0x1010f88, 0x30, 0xc420374870, 0xc42045d380, 0xc42045cd48)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags/parser.go:316 +0x893
github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags.(*Parser).Parse(0xc42001c960, 0x6, 0x17aa779, 0x6, 0x0, 0x17f2a5c)
	/Users/krasimir/src/github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags/parser.go:186 +0x73
main.main()
	/Users/krasimir/src/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go:105 +0x858

panics with the following swagger file.

swagger: '2.0'
info:
  version: 0.0.1
  title: User Management
basePath: /v1/
schemes:
  - http
produces:
  - application/json
consumes:
  - application/json
security:
  - jwt: []

paths:
  /user:
    get:
      summary: generates a list of users
      parameters:
        - in: query
          name: offset
          type: integer
          description: The number of items to skip before starting to collect the result set
        - in: query
          name: limit
          type: integer
          description: The numbers of items to return
      responses:
        200:
          description:  full user list
          schema:
            type: array
            items:
              properties:
                id:
                  type: integer
                username:
                  type: string
                created:
                  type: string
                f2a:
                  type: integer
        default:
          $ref: "#/responses/DefaultError"
  /user/login:
    post:
      security: []
      summary: generates a swt token to use for authentication
      parameters:
        - in: body
          name: body
          schema:
              $ref: "#/definitions/Login"

      responses:
        200:
          description: A jwt token to use for authentication.
          schema:
            $ref: "#/definitions/Jwt"
        206:
          description: Account is with 2 factor authenticaiton so use the 2 factor endpoint to generate the final the jwt token.
          schema:
            $ref: "#/definitions/Jwt"
        201:
          description: Password change is required, hit the password reset endpoint with the generated jwt token
          schema:
            $ref: "#/definitions/Jwt"
        default:
          $ref: "#/responses/DefaultError"
  /user/2fa:
    delete:
      summary: disable 2 factor authenticaiton for an account
      parameters:
        - in: body
          name: body
          schema:
            $ref:
              "#/definitions/F2aDisable"
      responses:
        200:
          description: 2fa disabled.
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    get:
      summary: generate qr base64 encoded image and master code for the user to scan with the google authenticator and add it to the phone app
      responses:
        200:
          description: A 2fa object.
          schema:
            properties:
              qr:
                type: string
              secret:
                type: string
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    put:
      summary: enables 2fa on an account
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/F2aEnable"
      responses:
        200:
          description: 2fa enabled.
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    post:
      summary: used when the account is with 2 factor authentication enabled. use the login endpoint first to get the initial jwt token and than use this endpoint to get the second jwt token after providing a valid google authenticator code
      security: []
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/F2aAuth"
      responses:
        200:
          description: the new jwt token that can be used for all endpoints.
          schema:
            $ref: "#/definitions/Jwt"
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
  /user/management:
    post:
      summary: creates a new user
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/Profile"
      responses:
        200:
          description: An user id of the created user.
          schema:
            type: object
            properties:
              id_profile:
                type: integer
        401:
          $ref: "#/responses/UnauthorizedError"
        409:
          $ref: "#/responses/UserExistsError"
        default:
          $ref: "#/responses/DefaultError"
    put:
      summary: updates an existing user, only submited fields will be updated so can ommit the ones that don't need updating
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/ProfileUpdate"
      responses:
        200:
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    delete:
      summary: deletes a user from the db
      parameters:
        - in: body
          name: body
          schema:
            type: object
            required:
            - id_profile
            properties:
              id_profile:
                type: integer
      responses:
        200:
          description: user deleted
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"

  /user/password:
    post:
      summary: reset an user password, when old password is not provided the user will be required to change its password upon next login using a temporary password provided by an admin
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/PassReset"
      responses:
        200:
          description: "user updated"
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    put:
      summary: resets an user password using a temporary password provided by an admin, once reset you can login as normal using the new password
      security: []
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/PassResetTemp"
      responses:
        200:
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
  /user/role:
    get:
      summary: generates a list of all user roles
      parameters:
        - in: query
          name: offset
          type: integer
          description: The number of items to skip before starting to collect the result set
        - in: query
          name: limit
          type: integer
          description: The numbers of items to return
      responses:
        200:
          description:  full roles list
          schema:
            type: array
            items:
              $ref: "#/definitions/UserRole"
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    post:
      summary: creates a new role
      parameters:
        - in: body
          name: body
          description: the id field here is not used so you can put any number to pass the validation
          schema:
            $ref: "#/definitions/UserRole"
      responses:
        200:
          description: the id of the created role.
          schema:
            type: object
            properties:
              id :
                type: integer
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    put:
      summary: updates a role
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/UserRole"
      responses:
        200:
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
    delete:
      summary: deletes a role
      parameters:
        - in: body
          name: body
          schema:
            type: object
            required:
            - id
            properties:
              id:
                type: integer
      responses:
        200:
          description: role deleted
        401:
          $ref: "#/responses/UnauthorizedError"
        default:
          $ref: "#/responses/DefaultError"
responses:
  UnauthorizedError:
    description: Authentication is missing or invalid
    schema:
      $ref: "#/definitions/Response"
  UserExistsError:
    description: Username already taken
    schema:
      $ref: "#/definitions/Response"
  DefaultError:
    description: Generic Error used for most error responses - it returns a custom code and message depending on the reply context
    schema:
      $ref: "#/definitions/Response"
definitions:
  Jwt:
      type: object
      required:
      - "jwt"
      properties:
        jwt:
          type: string
  F2aAuth:
      type: object
      required:
      - jwt
      - f2a
      properties:
        jwt:
          type: string
          description: the jwt token accuired form the initial login
        f2a:
          type: string
          description: the  2 factor time code accuired from the google authenticator app
  PassReset:
      type: object
      required:
      - "id_profile"
      - "password_new"
      properties:
        id_profile:
          type: integer
        password_old:
          type: string
        password_new:
          type: string
  PassResetTemp:
      type: object
      required:
      - jwt
      - passwordNew
      properties:
        jwt:
          type: string
          description: the jwt token accuired form the initial login
        passwordNew:
          type: string
          description: the new password for this user
  F2aDisable:
      type: object
      required:
      - password
      properties:
        password:
          type: string
  F2aEnable:
      type: object
      required:
        - code
        - secret
      properties:
        code:
          type: string
          description: the 2 factor code generted by the android app after scanning the barcode
        secret:
          type: string
          description: the master password which will be used to for decoding
  Login:
      type: object
      required:
        - username
        - password
      properties:
        username:
          type: string
        password:
          type: string
      example:
            username: "admin@mail.com"
            password: "password"
  Profile:
      type: object
      required:
      - username
      - password
      - active
      - role
      - tenant_id
      - person_id
      - reset_password_next_login
      properties:
        username:
          type: string
        password:
          type: string
        reset_password_next_login:
          type: boolean
        active:
          type: boolean
        email:
          type: string
        role:
            items:
                type: integer
        tenant_id:
          type: integer
        person_id:
          type: integer
      example:
            username: "username"
            email: "admin@mail.com"
            password: "password"
            active: true
            reset_password_next_login: false
            tenant_id: 1
            person_id: 1
            role:
              - 1
              - 2
  ProfileUpdate:
    type: object
    required:
      - id
    properties:
      id:
        type: integer
      username:
        type: string
      reset_password_next_login:
        type: string
        enum:
          - "true"
          - "false"

      password:
        type: string
      active:
        type: string
        enum:
          - "true"
          - "false"
      email:
        type: string
      role:
          items:
              type: integer
      tenant_id:
        type: integer
      person_id:
        type: integer
    example:
          id: 1
          username: "username"
          email: "admin@mail.com"
          password: "password"
          reset_password_next_login: "false"
          active: "true"
          tenant_id: 1
          person_id: 1
          role:
            - 1
            - 2
  UserRole:
      type: object
      required:
        - name
        - id
        - data
      properties:
        id:
          type: integer
        name:
          type: string
        data:
          type: string
  Response:
    type: object
    properties:
      code:
        type: integer
      message:
        type: string
    required:
      - code
      - message
    example:
          code: "500"
          message: "Server error"
securityDefinitions:
   jwt:
    type: apiKey
    in: header
    name: x-jwt

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (6 by maintainers)

Commits related to this issue

Most upvoted comments

👍 on no panic (on any input, not even, or even especially, bad input)